How to enable Slider Windows Phone Ticks property - slider

Here's what i want to do:
<Slider Minimum="1" Maximum="100" IsSnapToTickEnabled="True" Ticks="10,20,50,75,100" />
But here's the message Visual Studio display when on "IsSnapToTickEnable":
"The member IsSnapToTickEnabled is not recognized or is not accesible."
The same for Ticks. Why can't i use this feature in Windows Phone ?
Thanx
private void SliderValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
//Get The new value
int newValue = (int)e.NewValue;
//Set the new position
SliderAmount.Value = newValue;
}
The slider will go to position set as Value.
(In my example my slider parameters are Minimum="1" Maximum="5" SmallChange="1")

I found my answer:
private void SliderValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
//Get The new value
int newValue = (int)e.NewValue;
//Set the new position
SliderAmount.Value = newValue;
}
The slider will go to position set as Value.
(In my example my slider parameters are Minimum="1" Maximum="5" SmallChange="1")

thanks for your posting, which I found after many non working solutions. I was surprised that using discrete values this isn't a property of the slider and that a property like Ticks="1,2,3,4,5" won't work in a Windows Phone either. I found that it is important to warp the SliderAmount.Value = line in a Try-Catch because my emulator originally didn't even start the program anymore after adding the code. In the debugger I found that this was a System.NullReferenceException was unhandled by user code error (apparently on first init or something) and the Try/Catch solved that.

Related

UWP Reorder Gridviewitems on Xbox

I am making a UWP app which is supposed to be on xbox for now and maybe in future ill release it on pc and other platforms. I know that on PC and for mobile we can enable this feature with following 2 properties on the GridView or ListView.
CanReorderItems=True
CanDrop=True
But according to Microsoft Docs, drag and drop feature is not available or supported on xbox.
So what are any other options to achieve this reorder feature on xbox GridView?
UPDATE 1
So here is my backend code for the gridview. selection mode is single but I am not using selectionchanged event because that just creates lot of confusion and for now just assume that we always need to swap the items I will set the boolean later once the swapping in working perfectly.
private void SamplePickerGridView_ChoosingItemContainer(Windows.UI.Xaml.Controls.ListViewBase sender, ChoosingItemContainerEventArgs args)
{
if (args.ItemContainer != null)
{
return;
}
GridViewItem container = (GridViewItem)args.ItemContainer ?? new GridViewItem();
//should be xbox actually after pc testing
if (DeviceTypeHelper.GetDeviceFormFactorType() == DeviceFormFactorType.Desktop)
{
container.GotFocus += Container_GotFocus;
container.LostFocus += Container_LostFocus;
//container.KeyDown += Container_KeyDown;
}
args.ItemContainer = container;
}
private TVShow GotItem, LostItem;
private void Container_LostFocus(object sender, RoutedEventArgs e)
{
LostItem = OnNowAllGridView.ItemFromContainer(e.OriginalSource as GridViewItem) as TVShow;
GotItem = null;
}
private void Container_GotFocus(object sender, RoutedEventArgs e)
{
GotItem = OnNowAllGridView.ItemFromContainer(e.OriginalSource as GridViewItem) as TVShow;
if (GotItem != null && LostItem != null)
{
var focusedItem = GotItem;
var lostitem = LostItem;
var index1 = ViewModel.Source.IndexOf(focusedItem);
var index2 = ViewModel.Source.IndexOf(lostitem);
ViewModel.Source.Move(index1, index2);
}
LostItem = null;
}
u can try the code with adaptivegridview or just normal gridview of uwp if it works with that it should work with adaptivegridview as well.
Current Bheaviour items are swaped but the focus remains at same index.
Expected the focus should also move along with the item.
Your finding is true, drag and drop is not supported on Xbox out of the box (although when mouse support comes to Xbox in the future, I guess it will work).
So if you need this functionality, you will have to implement it manually from the start. One option would be to add a button, that will display on Xbox only and will read like Reorder Grid.
When this "reorder" mode were enabled, you have several solutions available.
The easiest solution for you would be to set the SelectionMode to Single and when a item is selected, you would bring it to fromt of the underlying collection.
collection.Remove( selectedItem );
collection.Insert( 0, selectedItem );
This bring to front solution was implemented on the Xbox One dashboard for reordering tiles.
Second option would be to set the SelectionMode to Multiple, where user would first select one item and then a second one. After that you could move the first selected item before the second selected:
collection.Remove( firstSelectedItem );
var targetIndex = collection.IndexOf( secondSelectedItem );
collection.Insert( targetIndex, firstSelectedItem );
The last solution is the most complex. With SelectionMode = Single you would select a single item and then observe the direction in which the user focus moves and move the tile "in real time". This is the most user friendly, but hardest to implement reliably.
Just as an outline of the third solution - you could capture the GotFocus event if you implement a custom template of the GridView:
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid Orientation="Horizontal"
GotFocus="GridViewItem_GotFocus"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
Now within this GotFocus handler you could retrieve the item that has currently focus from the EventArgs.OriginalSource. This way you could know which item got the focus and you could swap it with the item the user selected.
Update - hacky solution
I have come up with a hacky approach that solves the GotFocus/LostFocus mess.
The problem with GotFocus is that when we move the item in collection, the focus gets confused. But what if we didn't physically move the items at all?
Suppose your item type is TVShow. Let's create a wrapper around this type:
public class TVShowContainer : INotifyPropertyChanged
{
private TVShow _tvShow;
public TVShow TvShow
{
get => _tvShow;
set
{
_tvShow = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Now change the collection item type to this new "wrapper" type. Of course, you also have to update your GridView DataTemplate to have the right references. Instead of "{Binding Property}" you will now need to use "{Binding TvShow.Property}", or you can set the DataContext="{Binding TvShow}" attribute to the root element inside the DataTemplate.
But you may now see where I am going with this. Currently you are using Move method to move the items in the collection. Let's replace this with a swap:
var item1 = focusedItem.TvShow;
focusedItem.TvShow = LostItem.TvShow;
LostItem.TvShow = item1;
This is a big difference, because we no longer change the collection itself, but just move the references to items that are wrapped in a "static" container. And thanks to bindings the items will properly display where they should.
This is still a hacky solution, because it requires you to wrap your items just for the sake of the reordering, but it at least works. I am however still interested in finding a better way to do this.

How to change the value of SurfaceSlider without calling the ValueChanged event?

Im working with a MediaElement object and SurfaceSlider object, I use the SurfaceSlider to control the Video position and also want the SurfaceSlider to show the current position of the video, like youtube does.
I use this code to control the position of the video, this function is called when the ValueChanged event of the SurfaceSlider object occurs...
private void SeekToMediaPosition(object sender, RoutedPropertyChangedEventArgs<double> args)
{
int SliderValue = (int)mySurfaceSlider.Value;
TimeSpan ts = new TimeSpan(0, 0, 0, 0, SliderValue);
myMediaElement.Position = ts;
}
I use this code to show the current position of the video...
DispatcherTimer ticks = new DispatcherTimer();
private void Element_MediaOpened(object sender, EventArgs e)
{
mySurfaceSlider.Maximum = myMediaElement.NaturalDuration.TimeSpan.TotalMilliseconds;
ticks.Interval = TimeSpan.FromMilliseconds(1);
ticks.Tick += ticks_Tick;
ticks.Start();
myMediaElement.Play();
}
void ticks_Tick(object sender, object e)
{
mySurfaceSlider.Value = myMediaElement.Position.TotalMilliseconds;
}
The problem is when the SurfaceSlider value is changed showing the current position of the video, the ValueChanged event is called too, and the position of the video is changed, creating a loop I guess.
Is there any other event to be used when the user changes the SurfaceSlider value, or a way to handle this issue?
Thanks
Esteban,
I think there are a few things I would try.
1... Increase your TimeSpan.FromMilliseconds(1) to TimeSpan.FromMilliseconds(100) or higher. I don't think your slider needs to be polling your video so continuously.
2... I think you could set a flag in SeekToMediaPosition (SeekInProgress=true) before you set myMediaElement.Position. Then in ticks_Tick, if SeekInProgress==true, set SeekInProgress=false and don't set mySurfaceSlider.Value for one timer cycle.
I believe the original version of the code you are using comes from here: http://msdn.microsoft.com/en-us/library/ms748248.aspx ... Perhaps there is something that code was doing to prevent your problem that has been omitted from your implementation?
If the slider is jumping around, maybe there is lag between when the user places their finger down on the slider and when they move it (causing SeekToMediaPosition to fire). What you need to do is detect if the user is currently touching mySurfaceSlider in ticks_Tick (maybe there is a collection of touch points to query for intersection with mySurfaceSlider? Or does mySurfaceSlider have touchdown and touchup events?) In any case, if the user is even TOUCHING mySurfaceSlider, you shouldn't let ticks_Tick update mySurfaceSlider.Value (or for a few milliseconds after).

Context menu in windows 8 using Popup

Hi I am trying to create a context menu in windows 8 using Popup. On Right click of a button I am calling the following function
private async void UIElement_OnRightTapped(object sender, RightTappedRoutedEventArgs e)
{
PopupMenu popUpMenu = new PopupMenu();
popUpMenu.Commands.Add(new UICommand("File"));
Rect rect = GetRect(sender);
var result= await popUpMenu.ShowForSelectionAsync(rect, Placement.Right);
}
While defination for GetRect method is as follows:-
private Rect GetRect(object sender)
{
FrameworkElement element = sender as FrameworkElement;
GeneralTransform elementTransform = element.TransformToVisual(null);
Point point = elementTransform.TransformPoint(new Point());
Size size = new Size(element.ActualWidth, element.ActualHeight);
Rect rect = new Rect(point, size);
return rect;
}
Though the GetRect is returning correct value, but still i am getting result as null.
Please help
I can't figure out why you have this problems. On the first view, everything looks fine.
Maybe Tim Heuer Callisto package contains an easier approach for exactly what you want. See this example.
It's because you're not clicking on the File command, but instead clicking elsewhere on the page.

Windows 8 ads showing up on top of settings flyout

First, a screenshot:
The title and image explain it pretty well. I have an ad set on the right side of my app's main group view (very very similar to the default grid template in this example), and when I pull up my About screen, the ad bleeds through.
The About screen is a user control set on a SettingsFlyout that I borrowed from some code samples handed out at a dev-camp (below).
class SettingsFlyout
{
private const int _width = 346;
private Popup _popup;
public void ShowFlyout(UserControl control)
{
_popup = new Popup();
_popup.Closed += OnPopupClosed;
Window.Current.Activated += OnWindowActivated;
_popup.IsLightDismissEnabled = true;
_popup.Width = _width;
_popup.Height = Window.Current.Bounds.Height;
control.Width = _width;
control.Height = Window.Current.Bounds.Height;
_popup.Child = control;
_popup.SetValue(Canvas.LeftProperty, Window.Current.Bounds.Width - _width);
_popup.SetValue(Canvas.TopProperty, 0);
_popup.IsOpen = true;
}
private void OnWindowActivated(object sender, Windows.UI.Core.WindowActivatedEventArgs e)
{
if (e.WindowActivationState == Windows.UI.Core.CoreWindowActivationState.Deactivated)
{
_popup.IsOpen = false;
}
}
void OnPopupClosed(object sender, object e)
{
Window.Current.Activated -= OnWindowActivated;
}
}
And, because I know it will be asked for, here is the line of XAML defining the ad on my page:
<ads:AdControl Visibility="{Binding IsTrial, Source={StaticResource License}, Converter={StaticResource BooleanToVisibilityConverter}}" Grid.Row="0" Grid.RowSpan="2" x:Name="LandscapeAdControl" ApplicationId="test_client" AdUnitId="Image_160x600" Width="160" Height="600" VerticalAlignment="Center" HorizontalAlignment="Right"/>
So, why is this happening, and how do I prevent it?
Suspicions
I am still on Consumer Preview b/c I have a show-and-tell Monday and didn't have time to work on migrating the OS on this box without risking being non-functional when I am showing this. As such, upgrading might fix it if it's a bug.
1.a. Update I have upgraded to Release Preview and have the same issue.
Is there some fancy ad-hiding-but-still-getting-impressions prevention technique at play here? Perhaps it thinks I am trying to cover the ad with a ui element and still get credit for it's impression without the user seeing it. If so, how do I manage this entirely legit use case?
Spoiler Alert: ZIndex isn't set anywhere.
It presents the same problem with overlaying the AppBar (top or bottom). I used the Opened and Closed events on the AppBar instance to hide/show the ad. This means the AdControl is bound to a local page property instead of binding directly to a ViewModel. Like you said, it's unfortunate but it works.
private void bottomAppBar_Opened(object sender, object e)
{
if (App.ViewModel.IsTrialVisibility == Visibility.Visible)
this.DefaultViewModel["AdVisibility"] = Visibility.Collapsed;
// else do nothing as we don't want to show it since it's not a trial
}
private void bottomAppBar_Closed(object sender, object e)
{
if(App.ViewModel.IsTrialVisibility == Visibility.Visible)
this.DefaultViewModel["AdVisibility"] = Visibility.Visible;
// else do nothing as it's not shown in the first place (not a trial)
}
There is a property on AdControl named: UseStaticAnchor
Setting this property to true will fix both performance problems with scrolling, as well as the AdControl drawing on top of everything else.
Original answer - this method is now outdated:
The AdControl has two methods on it: Suspend() and Resume().
Whenever you open a popup window or AppBar, you will want to call Suspend(), and Resume() when it is closed again.
I believe under the covers, the AdControl uses a WebView to display the ads. For whatever reason, a WebView will always display on top of everything else in your application. The fix for this is to temporarily disable the WebView, and instead display a WebViewBrush.
(This technique is described here: http://msdn.microsoft.com/library/windows/apps/windows.ui.xaml.controls.webviewbrush) So when you call Suspend() and Resume(), the AdControl is doing this under the covers.
What I've ended up doing is creating a UserControl (named SuspendingAdControl) that simply contains an AdControl and can be used anywhere in the app. Then whenever a window is opened or closed, I use Caliburn Micro's EventAggregator to publish an event. The SuspendingAdControl will subscribe and handle these events, and then appropriately call AdControl.Suspend() or Resume().
I ended up crafting some code to listen to an event on the flyout when it closed so I could high/show the ads manually. It's unfortunate that I had to do a workaround, but it works.
None of this is now necessary, as the flyout in 8.1 now is at the top of the Z-order.
I am still on Consumer Preview b/c I have a show-and-tell Monday and
didn't have time to work on migrating the OS on this box without
risking being non-functional when I am showing this. As such,
upgrading might fix it if it's a bug.
I haven't used any advertisements in my own metro applications yet, so I haven't seen any problems like this occurring. I'm using the Release Preview, and was using Consumer Preview prior to May 2nd.
There were some significant changes between the Consumer Preview and Release Preview. As such, upgrading might fix this, or it may break something else.
You're going to have to upgrade eventually. I'd suggest trying that first before you attempt to solve the problem.

Why would VisualTreeHelper.FindElementsInHostCoordinates return no results?

Working on a Metro style app in C#. I have a custom control which inherits from Grid. MyGrid contains some other custom controls. I'm trying to do hit testing on those controls in the PointerReleased handler:
void MyGrid_PointerReleased(object sender, PointerRoutedEventArgs e)
{
PointerPoint pt = e.GetCurrentPoint(this);
var hits = VisualTreeHelper.FindElementsInHostCoordinates(pt.Position, this);
int breakhere = hits.Count();
}
After this code executes, hitCount is 0. If I move the PointerReleased handler one control higher in the visual tree heirarchy then hitCount is correct the first time and 0 after that. I set up a test project with similar XAML layout to try to reproduce the problem and it works correctly every time. So I'm not sure what bad thing I have done that is preventing VisualTreeHelper from working. I'm not really sure how to proceed debugging this. Any ideas what would cause this function to return no results?