简体   繁体   English

导航后,依赖项属性恢复为默认值

[英]Dependency Property reverting to default value after navigation

I'm missing something really obvious here but just cant work it out :( 我在这里遗漏了一些非常明显的东西,但是无法解决:(

I have a 2 page windows store application with a Dependency Property called Seconds. 我有一个2页的Windows存储应用程序,其Dependency Property称为Seconds。 If you click the start button a timer will start and the value of Seconds will decrease as expected BUT if I navigate to Page2 and back again to MainPage the DP is reset to Default Value in UI despite the actual value being correct. 如果单击开始按钮,计时器将启动,并且如果我导航到Page2然后再次返回到MainPage ,则Seconds的值将按预期的BUT减小,尽管实际值正确,但DP在UI中仍重置为默认值。

I can see this by putting a breakpoint on the _timer.tick event the Seconds DP isnt at its default value but decreasing as expected as the timer is still running. 我可以通过在_timer.tick事件上设置一个断点来查看此情况, Seconds DP不会将其设置为默认值,但由于计时器仍在运行,因此可以按预期减少。 I would like this reflected in the UI Any help appreciated? 我想在用户界面中体现这一点任何帮助表示赞赏吗?

MainPage.xaml MainPage.xaml中

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="1*"/>
        <ColumnDefinition Width="1*"/>
    </Grid.ColumnDefinitions>
    <StackPanel>
        <Button x:Name="btnNav" Content="Page 2" Width="150" Height="60" Click="btnNav_Click"></Button>
        <Button x:Name="btnStart" Content="Start" Width="150" Height="60" Click="btnStart_Click"></Button>
    </StackPanel>
    <StackPanel Grid.Column="1">            
        <TextBlock x:Name="txtSeconds" FontSize="25" Text="{Binding Path=Seconds}" />
    </StackPanel>
</Grid>

MainPage.cs MainPage.cs

 public sealed partial class MainPage : Page
 {
    private static DispatcherTimer _timer;

    public MainPage()
    {
        this.InitializeComponent();

        Loaded += (s, args) =>
            {


                if (_timer == null)
                {
                    _timer = new DispatcherTimer();
                    _timer.Interval = TimeSpan.FromMilliseconds(1000);
                    _timer.Tick += (sender, e) =>
                        {                                
                            Seconds--;
                        };
                }

                this.DataContext = this;
            };
    }


    public int Seconds
    {
        get { return (int)GetValue(SecondsProperty); }
        set { SetValue(SecondsProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Seconds.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty SecondsProperty =
        DependencyProperty.Register("Seconds", typeof(int), typeof(MainPage), new PropertyMetadata(100));


    private void btnNav_Click(object sender, RoutedEventArgs e)
    {
        this.Frame.Navigate(typeof(Page2));
    }

    private void btnStart_Click(object sender, RoutedEventArgs e)
    {
        _timer.Start();
    }
}

Page2.xaml Page2.xaml

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <AppBarButton Icon="Back" Click="AppBarButton_Click"></AppBarButton>
</Grid>

Page2.cs Page2.cs

public sealed partial class Page2 : Page
{
    public Page2()
    {
        this.InitializeComponent();
    }

    private void AppBarButton_Click(object sender, RoutedEventArgs e)
    {
        this.Frame.Navigate(typeof(MainPage));
    }
}

As stated in comment : 如评论所述:

Problem is not in DP. 问题不在DP中。 When you navigate back to same page, page is recreated. 当您导航回到同一页面时,将重新创建页面。 You can verify that by putting breakpoint on MainPage constructor. 您可以通过在MainPage构造函数上放置断点来验证这一点。 Since after navigating back to main page, you haven't started timer again so no update in GUI. 由于导航回到主页后,您没有再次启动计时器,因此没有GUI更新。

For your statement 为您的陈述

_timer is static. _timer是静态的。

that change nothing at all. 完全没有改变。 Since timer is static and won't be null in case of second load so Tick event never gets hooked up for second instance of MainPage. 由于timer是静态的,并且在第二次加载的情况下不会为null,因此Tick事件永远不会挂接到MainPage的第二个实例。

Tick event is getting hit for first instance of MainPage. Tick事件正在被MainPage的第一个实例击中。 First instance never gets destroyed because of memory leak you have induced by making timer as static. 实例永远不会因为将计时器设为静态而引起的内存泄漏而销毁。 So, it is still decrementing Seconds value for first instance and not current instance. 因此,对于第一个实例而不是当前实例,它仍在递减Seconds值。

Move Tick event hooking outside of null check and you will see GUI will update but starting from 100 onwards because new instance will have default value 100. Tick事件挂钩移至null检查之外,您将看到GUI将更新,但将从100开始,因为新实例的默认值为100。

 if (_timer == null)
 {
     _timer = new DispatcherTimer();
     _timer.Interval = TimeSpan.FromMilliseconds(1000);
 }
 _timer.Tick += (sender, e) =>
            {                                
               Seconds--;
            };

As mentioned in comments, you navigate forward to new instance of MainPage, so it has own (default) value of DP. 如注释中所述,您将向前导航到MainPage的新实例,因此它具有自己的(默认)DP值。

I guess you're looking for GoBack method of Frame 我想您正在寻找Frame的GoBack方法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM