UWP Loop Fade Animation - xaml

I have a Pivot and its header template is a user control and I want to start a continuous Flashing ( Fade Out Fade In ) animation on it on a specific trigger and then also want to stop it on a specific trigger, while both of these triggers/events will happen in the ViewModel of the page. I can take care of the triggers but my only issue is I am not sure how to achieve the infinite flashing behavior. The header has to start flashing when I tell it to and has to keep flashing until I tell it to stop. I wonder if there is some sort of Repeat animation property in xaml but couldn't find that in xaml animations from Community Toolkit
Queue is the model class which defines the context of HeaderTemplate, so I've custom events to start and stop the flashing, because I have access to that Queue object instance within the ViewModel of my page.
All the custom logic happens in code behind of the User Control. Attached is the code I have tried below. I would prefer if this is somehow done all in xaml or mostly in xaml so I can avoid any infinite loops or memory leak risks. My current attempt just freezes the UI and rightly so as I am doing an infinite loop which makes stuff just weird.
Code
Pivot Header
<Pivot.HeaderTemplate>
<DataTemplate x:DataType="cad:Queue">
<dataTemplates:HomePivotHeaderTemplate />
</DataTemplate>
</Pivot.HeaderTemplate>
Queue class
public partial class Queue
{
public event EventHandler<EventArgs> StartFlash;
public event EventHandler<EventArgs> StopFlash;
public void OnStartFlash() => StartFlash?.Invoke(this, EventArgs.Empty);
public void OnStopFlash() => StopFlash?.Invoke(this, EventArgs.Empty);
}
Triggers in ViewModel
public void StartFlashingPendingQueues()
{
PivotQueues.First()?.OnStartFlash();
}
private void StopFlashingPendingQueues()
{
PivotQueues.First()?.OnStopFlash();
}
UserControl for Data Template
public sealed partial class HomePivotHeaderTemplate : UserControl
{
public Queue VM => DataContext as Queue;
private bool _IsFlashing;
private bool _unLoaded;
public HomePivotHeaderTemplate()
{
InitializeComponent();
Loaded += HomePivotHeaderTemplate_Loaded;
Unloaded += HomePivotHeaderTemplate_Unloaded;
DataContextChanged += (s, e) => Bindings.Update();
}
private void HomePivotHeaderTemplate_Unloaded(object sender, RoutedEventArgs e)
{
_unLoaded = true;
Loaded -= HomePivotHeaderTemplate_Loaded;
Unloaded -= HomePivotHeaderTemplate_Unloaded;
VM.StartFlash -= VM_StartFlash;
VM.StopFlash -= VM_StopFlash;
}
private void HomePivotHeaderTemplate_Loaded(object sender, RoutedEventArgs e)
{
VM.StartFlash += VM_StartFlash;
VM.StopFlash += VM_StopFlash;
VM_Flashed();
}
private void VM_StopFlash(object sender, System.EventArgs e) => _IsFlashing = false;
private void VM_StartFlash(object sender, System.EventArgs e) => _IsFlashing = true;
private async Task VM_Flashed()
{
while (true)
{
if (_unLoaded)
{
break;
}
else
{
if (_IsFlashing)
{
await Block.Fade(value: 0f, duration: 500, delay: 0, easingType: EasingType.Linear, easingMode: EasingMode.EaseOut).Then().Fade(value: 1f, duration: 500, delay: 0, easingType: EasingType.Linear, easingMode: EasingMode.EaseIn).StartAsync();
}
}
}
}
}
Edit 1
If I can somehow figure out how to give infinite flashing animation to the textblock I can take care of the rest. basically I could just have 2 textblocks identical, one of them will be flashing other won't, and I can toggle their visibility based on triggers in my viewmodel.

I guess I was just overthinking it. It was a simple DoubleAnimation in a StoryBoard
UserControl code behind
public sealed partial class HomePivotHeaderTemplate : UserControl
{
public Queue VM => DataContext as Queue;
public HomePivotHeaderTemplate()
{
InitializeComponent();
Loaded += HomePivotHeaderTemplate_Loaded;
Unloaded += HomePivotHeaderTemplate_Unloaded;
DataContextChanged += (s, e) => Bindings.Update();
}
private void HomePivotHeaderTemplate_Unloaded(object sender, RoutedEventArgs e)
{
Loaded -= HomePivotHeaderTemplate_Loaded;
Unloaded -= HomePivotHeaderTemplate_Unloaded;
VM.StartFlash -= VM_StartFlash;
VM.StopFlash -= VM_StopFlash;
}
private void HomePivotHeaderTemplate_Loaded(object sender, RoutedEventArgs e)
{
VM.StartFlash += VM_StartFlash;
VM.StopFlash += VM_StopFlash;
}
private void VM_StopFlash(object sender, System.EventArgs e) => FlashStoryBoard.Stop();
private void VM_StartFlash(object sender, System.EventArgs e) => FlashStoryBoard.Begin();
}
UserControl Xaml
<UserControl.Resources>
<Storyboard x:Name="FlashStoryBoard">
<DoubleAnimation Storyboard.TargetName="Block" Storyboard.TargetProperty="Opacity"
Duration="0:0:2"
From="1"
RepeatBehavior="Forever"
To="0.2" />
</Storyboard>
</UserControl.Resources>
<TextBlock x:Name="Block"
Text="{x:Bind VM.Name}" />

Related

Trying to play video after splash screen in uwp

Hi I'm trying to play a video of 3sec after splash screen .But the issue is that not any video is playing for 3sec and then it redirect to "Home" screen.
Here is the code for that.Any help would be appreciated.
xaml
<Grid>
<MediaElement x:Name="myMediaElement" CurrentStateChanged="MediaElement_CurrentStateChanged"/>
</Grid>
Cs code
public sealed partial class MainPage : Page
{
internal Frame rootFrame;
public MainPage()
{
this.InitializeComponent();
myMediaElement.Source = new Uri("ms-appx:///Assets/Videos/splash_3.mp4");
myMediaElement.AutoPlay = true;
DissmissExtendedSplash();
}
private void MediaElement_CurrentStateChanged(object sender, RoutedEventArgs e)
{
if (myMediaElement.CurrentState == MediaElementState.Paused)
{
this.Frame.Navigate(typeof(Home));
}
}
MediaElement has CurrentStateChanged Event which is what you are looking for. Move your Navigation even to this method and it should work for you as intended.
<Grid>
<MediaElement x:Name="myMediaElement" CurrentStateChanged="MediaElement_CurrentStateChanged"/>
</Grid>
Below is how you need to check MediaElement.CurrentState to Navigate.
private void MediaElement_CurrentStateChanged(object sender, RoutedEventArgs e)
{
if (myMediaElement.CurrentState == MediaElementState.Paused)
{
this.Frame.Navigate(typeof(Home));
}
}

Win RT Xaml GridView: Drag select multiple items

I'm trying to select multiple items in a GridView by hovering over them with pressed mouse (like drawing). I tried to achieve this with the PointerEntered event but I'm unable to change the selction from code. Is there a way to implement a custom selection mode?
This didn't work for me because I can't use Style.Triggers in Win RT XAML:
https://stackoverflow.com/a/2886223/5739170
You will have to inherit the gridview control and override the PrepareContainerForItemOverride method:
The code:
public class MyGridView : GridView
{
protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
{
(element as GridViewItem).PointerMoved += MyGridView_PointerMoved;
base.PrepareContainerForItemOverride(element, item);
}
private void MyGridView_PointerMoved(object sender, PointerRoutedEventArgs e)
{
//your logic for setting the isselected
(sender as GridViewItem).IsSelected = true;
}
}
This is how I finally implemented it based on Chirag Shah's answer:
class MyGridView : GridView
{
protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
{
(element as GridViewItem).PointerEntered += SelectItemOnEntered;
(element as GridViewItem).AddHandler(PointerPressedEvent, new PointerEventHandler(SelectItemOnPressed), true);
base.PrepareContainerForItemOverride(element, item);
}
private void SelectItemOnPressed(object sender, PointerRoutedEventArgs e)
{
(sender as GridViewItem).IsSelected = !(sender as GridViewItem).IsSelected;
}
private void SelectItemOnEntered(object sender, PointerRoutedEventArgs e)
{
if (e.Pointer.IsInContact)
(sender as GridViewItem).IsSelected = !(sender as GridViewItem).IsSelected;
}
}
I hope this helps everyone who wants to implement this selection mode.

UWP ListView drag behavior for touch

When using touch to trigger a drag and drop action for a ListView item, it would appear that the behavior has changed between WinRT (Windows 8/8.1) and UWP (Windows 10) apps.
In WinRT, "tearing" an item to the left or right would cause it to get detached, initiating the drag behavior. In UWP, the user has to tap and hold an item for a short while, after which moving it initiates the drag action.
My question is: is there a way to revert to/implement the old WinRT-style behavior? The new way is not very obvious and in limited user testing I haven't seen one person work it out without having it explained to them.
As a quick example, the following XAML works for both WinRT and UWP, however the touch-based interactions are much discoverable in WinRT.
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ListView AllowDrop="True" CanReorderItems="True">
<ListView.Items>
<x:String>Item 1</x:String>
<x:String>Item 2</x:String>
<x:String>Item 3</x:String>
<x:String>Item 4</x:String>
<x:String>Item 5</x:String>
</ListView.Items>
</ListView>
</Grid>
I wanted similar behaviour that was questioned here as I was annoyed with the default win10 behaviour. There might be better solutions, but this one is what I came up.
<GridView Name="MySourceGridView" ItemsSource="{x:Bind Animals}" ScrollViewer.VerticalScrollMode="Disabled" >
<GridView.ItemTemplate>
<DataTemplate x:DataType="data:Animal">
<StackPanel Margin="20" Width="200" Height="200" PointerPressed="StackPanel_PointerPressed" DragStarting="StackPanel_DragStarting">
<StackPanel.Background>
<SolidColorBrush Color="{x:Bind Color}" />
</StackPanel.Background>
<TextBlock Text="{x:Bind Name}" />
</StackPanel>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
Above is my GridView and binded data. I noticed that if I use gridviews candrop and dragstarted events, I just couldn't do what I liked. So I used datatemplates stackpanels pointerpressed, which launches immediatly on touch.
private async void StackPanel_PointerPressed(object sender, PointerRoutedEventArgs e)
{
var obj = (StackPanel)sender;
if (obj != null)
{
var pointerPoint = e.GetCurrentPoint(sender as UIElement);
await obj.StartDragAsync(pointerPoint);
}
}
There you have the pointerPoint too. The dragstarted on the stackpanel to move the data.
private void StackPanel_DragStarting(UIElement sender, DragStartingEventArgs args)
{
var senderElement = sender as FrameworkElement;
var ani = (Animal)senderElement.DataContext;
args.Data.SetText(ani.ID.ToString());
args.Data.RequestedOperation = DataPackageOperation.Copy;
}
Rest is just the normal data catching after I managed to pass the ID of the Animal in my list of animals forward.
private void MyTargetRectangle_DragEnter(object sender, DragEventArgs e)
{
e.AcceptedOperation = DataPackageOperation.Copy;
e.DragUIOverride.Caption = "Kokeiles";
e.DragUIOverride.IsCaptionVisible = true;
e.DragUIOverride.IsContentVisible = true;
e.DragUIOverride.IsGlyphVisible = false;
}
private async void MyTargetRectangle_Drop(object sender, DragEventArgs e)
{
var droppedAnimalId = await e.DataView.GetTextAsync();
Animal ani = Animals.Where(p => p.ID == int.Parse(droppedAnimalId)).FirstOrDefault();
MyTargetRectangle.Fill = new SolidColorBrush(ani.Color);
}
I hope this helps someone and is not too long answer.
I've finally figured out how to get back the old Windows 8.1 behavior for the ListView. It still allows Scrolling with touch and starts a drag operation of one item if you swipe perpendicularly to the scroll axis. It's based on the Comet library and is implemented by a custom ListView. The idea is to allow TranslateX/TranslateY and System Manipulations in the ListViewItem. For this you need to override the default ListViewItem's style.
If you want to use the control, you have to bear in mind a few things:
Copy the styles in Themes/Generic.xaml and adapt the local2 Namespace.
If you use a horizontally scrolling ListView, you must set the Orientation property of the ListView accordingly. The control doesn't detect the used ItemsPanel.
You can still use the regular UWP drag & drop mechanism, but you must subscribe to a second Event called ItemStartDragging for the old Windows 8.1 style dragging.
If you handle the Drop event when using the 8.1 style dragging, the data can be found in DragEventArgs.DataView, whereas it could be found in DragEventArgs.Data.GetView() when using DragItemStarting (=default event). Don't know why they behave differently.
The styles are very basic. You might want to change them and make them more akin to the original ListViewItem styles.
Here's the code:
public class DraggingListView : ListView
{
public DraggingListView()
{
}
protected override DependencyObject GetContainerForItemOverride()
{
if (Orientation == Orientation.Horizontal)
return new HorizontalDraggingListItem(this);
else
return new VerticalDraggingListItem(this);
}
protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
{
base.PrepareContainerForItemOverride(element, item);
(element as DraggingListItem).DataContext = item;
(element as DraggingListItem).MouseSlidingEnabled = MouseSlidingEnabled;
}
public event EventHandler<ListItemStartDraggingEventArgs> ItemStartDragging;
public void OnChildItemDragged(DraggingListItem item, Windows.ApplicationModel.DataTransfer.DataPackage data)
{
if (ItemStartDragging == null)
return;
ItemStartDragging(this, new ListItemStartDraggingEventArgs(data, item.DataContext));
}
public Orientation Orientation
{
get { return (Orientation)GetValue(OrientationProperty); }
set { SetValue(OrientationProperty, value); }
}
public static readonly DependencyProperty OrientationProperty =
DependencyProperty.Register("Orientation", typeof(Orientation), typeof(DraggingListView), new PropertyMetadata(Orientation.Vertical));
/// <summary>
/// Gets or sets the ability to slide the control with the mouse. False by default
/// </summary>
public bool MouseSlidingEnabled
{
get { return (bool)GetValue(MouseSlidingEnabledProperty); }
set { SetValue(MouseSlidingEnabledProperty, value); }
}
public static readonly DependencyProperty MouseSlidingEnabledProperty =
DependencyProperty.Register("MouseSlidingEnabled", typeof(bool), typeof(DraggingListView), new PropertyMetadata(false));
}
public class ListItemStartDraggingEventArgs : EventArgs
{
public Windows.ApplicationModel.DataTransfer.DataPackage Data { get; private set; }
public object Item { get; private set; }
public ListItemStartDraggingEventArgs(Windows.ApplicationModel.DataTransfer.DataPackage data, object item)
{
Data = data;
Item = item;
}
}
public class HorizontalDraggingListItem : DraggingListItem
{
public HorizontalDraggingListItem(DraggingListView listView) : base(listView)
{
this.DefaultStyleKey = typeof(HorizontalDraggingListItem);
}
protected override bool DetectDrag(ManipulationDelta delta)
{
return Math.Abs(delta.Translation.Y) > 2;
}
}
public class VerticalDraggingListItem : DraggingListItem
{
public VerticalDraggingListItem(DraggingListView listView) : base(listView)
{
this.DefaultStyleKey = typeof(VerticalDraggingListItem);
}
protected override bool DetectDrag(ManipulationDelta delta)
{
return Math.Abs(delta.Translation.X) > 2;
}
}
[TemplatePart(Name = PART_CONTENT_GRID, Type = typeof(Grid))]
public abstract class DraggingListItem : ListViewItem
{
const string PART_CONTENT_GRID = "ContentGrid";
private Grid contentGrid;
private DraggingListView _listView;
public DraggingListItem(DraggingListView listView)
{
_listView = listView;
this.DragStarting += OnDragStarting;
}
private void OnDragStarting(UIElement sender, DragStartingEventArgs args)
{
_listView.OnChildItemDragged(this, args.Data);
}
protected override void OnApplyTemplate()
{
contentGrid = this.GetTemplateChild(PART_CONTENT_GRID) as Grid;
contentGrid.ManipulationDelta += ContentGrid_ManipulationDelta;
contentGrid.ManipulationCompleted += ContentGrid_ManipulationCompleted;
contentGrid.PointerPressed += ContentGrid_PointerPressed;
base.OnApplyTemplate();
}
private PointerPoint pp = null;
private void ContentGrid_PointerPressed(object sender, PointerRoutedEventArgs e)
{
if (!MouseSlidingEnabled && e.Pointer.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Mouse)
return;
pp = e.GetCurrentPoint(sender as UIElement);
}
private void ContentGrid_ManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
{
if (!MouseSlidingEnabled && e.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Mouse)
return;
pp = null;
}
private async void ContentGrid_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
if (!MouseSlidingEnabled && e.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Mouse)
return;
if (DetectDrag(e.Delta) && pp != null)
{
var pointer = pp;
pp = null;
await StartDragAsync(pointer);
}
}
protected abstract bool DetectDrag(ManipulationDelta delta);
#region Dependency Properties
/// <summary>
/// Gets or sets the ability to slide the control with the mouse. False by default
/// </summary>
public bool MouseSlidingEnabled
{
get { return (bool)GetValue(MouseSlidingEnabledProperty); }
set { SetValue(MouseSlidingEnabledProperty, value); }
}
public static readonly DependencyProperty MouseSlidingEnabledProperty =
DependencyProperty.Register("MouseSlidingEnabled", typeof(bool), typeof(DraggingListItem), new PropertyMetadata(false));
#endregion
}
And this is the XAML in Generic.xaml:
<Style TargetType="local2:HorizontalDraggingListItem" >
<Setter Property="VerticalAlignment" Value="Stretch"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local2:HorizontalDraggingListItem">
<Grid ManipulationMode="TranslateY,System" x:Name="ContentGrid" Background="{TemplateBinding Background}">
<ContentPresenter />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="local2:VerticalDraggingListItem" >
<Setter Property="HorizontalAlignment" Value="Stretch"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local2:VerticalDraggingListItem">
<Grid ManipulationMode="TranslateX,System" x:Name="ContentGrid" Background="{TemplateBinding Background}">
<ContentPresenter />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
In WinRT, "tearing" an item to the left or right would cause it to get detached, initiating the drag behavior. In UWP, the user has to tap and hold an item for a short while, after which moving it initiates the drag action.
Yes, the Behavior to start Drag action has been changed in UWP app.
My question is: is there a way to revert to/implement the old WinRT-style behavior?
The possible way is to create a Drag Behavior and attach to ListView, in this Behavior, we can handle the related touch event and use UIElement.StartDragAsync method to initiates a drag-and-drop operation programmatically, to find the current ListViewItem,
public class FrameworkElementDragBehavior : DependencyObject, IBehavior
{
private bool isMouseClicked = false;
public DependencyObject AssociatedObject { get; private set; }
public void Attach(DependencyObject associatedObject)
{
var control = associatedObject as Control;
if (control == null)
throw new ArgumentException(
"FrameworkElementDragBehavior can be attached only to Control");
AssociatedObject = associatedObject;
((FrameworkElement)this.AssociatedObject).Holding += FrameworkElementDragBehavior_Holding;
((FrameworkElement)this.AssociatedObject).DragStarting += FrameworkElementDragBehavior_DragStarting;
}
private void FrameworkElementDragBehavior_Holding(object sender, Windows.UI.Xaml.Input.HoldingRoutedEventArgs e)
{
//Just for example, not the completed code
var obj = ((ListView)sender).SelectedItem as ListViewItem;
if (obj != null)
{
//Call the UIElement.StartDragAsync method
}
}
private void FrameworkElementDragBehavior_DragStarting(UIElement sender, DragStartingEventArgs args)
{
throw new NotImplementedException();
}
public void Detach()
{
AssociatedObject = null;
}
}

HardwareButtons.BackPressed event gets unregistered automatically when my app goes to background in windows phone 8.1 app

I am using prism for my windows phone 8.1 runtime app, i want few conditions to be written in my code on backbutton press, so even though prism will take care of hardware backbutton flow i need to handle it in my local page(either inside cs page or view model), so i override the OnHardwareButtonsBackPressed method in my app.cs page and in my local page i will register and unregister hardware backbutton event in onnavigatedto and onnavigatedfrom method respectively and write my logic, it works fine for me until the app goes background, once if my app goes background and comes back the registered hardware backbutton event is unregistered automatically and from then the back flow is not working.
//App.cs
public sealed partial class App : MvvmAppBase
{
public App()
{
this.InitializeComponent();
}
protected override Task OnLaunchApplicationAsync(LaunchActivatedEventArgs args)
{
NavigationService.Navigate("Main", null);
return Task.FromResult<object>(null);
}
#if WINDOWS_PHONE_APP
protected async override void OnHardwareButtonsBackPressed(object sender, Windows.Phone.UI.Input.BackPressedEventArgs e)
{
var currentFrame = Window.Current.Content as Frame;
var currentView = currentFrame.Content as IView;
if (currentView != null)
{
var backNavigationVM = currentView.DataContext as IBackNavigation;
if ((backNavigationVM == null || backNavigationVM.CanGoBack))
{
base.OnHardwareButtonsBackPressed(sender, e);
}
else
{
e.Handled = true;
}
}
else
{
e.Handled = true;
}
}
#endif
}
//My page.xaml
<storeApps:VisualStateAwarePage
x:Class="BackButtonWithPrism.Views.SecondPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:BackButtonWithPrism.Views"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
xmlns:storeApps="using:Microsoft.Practices.Prism.StoreApps"
xmlns:mvvm="using:Microsoft.Practices.Prism.Mvvm"
mvvm:ViewModelLocator.AutoWireViewModel="True">
<Grid>
<TextBlock Text="SecondPage" FontSize="{StaticResource TextStyleLargeFontSize}" HorizontalAlignment="Center"></TextBlock>
<Grid x:Name="FirstGrid">
<Button HorizontalAlignment="Center" Content="FirstGrid" Click="Button_Click"></Button>
</Grid>
<Grid x:Name="SecondGrid">
<Button HorizontalAlignment="Center" x:Name="btnSecond" Content="SecondGrid"></Button>
</Grid>
</Grid>
</storeApps:VisualStateAwarePage>
//My page.cs
public sealed partial class SecondPage : VisualStateAwarePage
{
public SecondPage()
{
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
}
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
FirstGrid.Visibility = Visibility.Visible;
SecondGrid.Visibility = Visibility.Collapsed;
#if WINDOWS_PHONE_APP
Windows.Phone.UI.Input.HardwareButtons.BackPressed += HardwareButtons_BackPressed;
#endif
}
#if WINDOWS_PHONE_APP
private async void HardwareButtons_BackPressed(object sender, Windows.Phone.UI.Input.BackPressedEventArgs e)
{
if (FirstGrid.Visibility == Visibility.Collapsed)
{
e.Handled = true;
FirstGrid.Visibility = Visibility.Visible;
SecondGrid.Visibility = Visibility.Collapsed;
}
else
{
Frame currentFrame = Window.Current.Content as Frame;
if (currentFrame == null)
{
return;
}
else if (currentFrame.CanGoBack)
{
currentFrame.GoBack();
e.Handled = true;
}
}
}
#endif
protected async override void OnNavigatedFrom(NavigationEventArgs e)
{
Windows.Phone.UI.Input.HardwareButtons.BackPressed -= HardwareButtons_BackPressed;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
FirstGrid.Visibility = Visibility.Collapsed;
SecondGrid.Visibility = Visibility.Visible;
}
}
//My Page ViewModel:
public class SecondPageViewModel : ViewModel, IBackNavigation
{
public bool CanGoBack
{
get;
set;
}
}
here all my logic i have written in my cs page instead of writting in viewmodel but i ill do it later.
Your problem is related to OnNavigatedFrom() implementation. This method is called, when the application is deactivated and goes to background, causing deregistration of back-button handler. Unfortunately the OnNavigatedTo() is not called to pair it, when application is activated. Instead another event should be handled - Window.Activated. If you don't want to complicate your code to much, just try to put wrap removal of back-button handler with following condition. Forward request with a type of a current page is passed, when app goes to background.
if (e.NavigationMode != NavigationMode.Forward || e.SourcePageType != GetType())
{
HardwareButtons.BackPressed -= ...
}
One final hint. When you put a breakpoint inside the IDE and launch debugger application will never be suspended and will never receive respective events. To simulate them (i.e. activated, suspended, and terminated) check here or here.

Why Won't the Silverlight ChildWindow Display?

I have a simple Silverlight 4 application and have added a child window to it. I am using the below code to open it on a button click. This seems like it should work, does it not?
public void btnAbout_Click(object sender, RoutedEventArgs e)
{
About aboutThis = new About();
aboutThis.Show();
}
The "About" class looks like this:
public partial class About : ChildWindow
{
public About()
{
InitializeComponent();
}
private void OKButton_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = true;
}
private void CancelButton_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = false;
}
}
I don't see any reason why it should not work.
Samples:
http://www.tanguay.info/web/index.php?pg=codeExamples&id=135
http://www.silverlighttoys.com/Tutorials.aspx?tutorial=2
What is your XAML like?
Try setting the Width and Height to 600px by 600px of your About Childwindow from xaml.