UWP应用程序未更新视图

问题描述:

简单练习:在UWP应用程序的Textblock中显示当前时间。 我正在使用MVVMlight和PropertyChanged.Fody。UWP应用程序未更新视图

至于这个例子基地我使用这个Article 1文章和MVVMlight/Fody实现从这里:Article 2

我有一个MainViewModel。在这里,我创建了DateTimeModel类的一个实例,并且如果引发属性更改事件(工作),我已经添加了一个调试输出。

using System.Diagnostics; 
 
using GalaSoft.MvvmLight; 
 
using Logic.Ui.Models.DateTime; 
 
using PropertyChanged; 
 

 
namespace Logic.Ui 
 
{ 
 
    public class MainViewModel : ViewModelBase, INotifyPropertyChanged 
 
    { 
 

 
     public DateTimeModel DateTimeModel; 
 

 
     [DependsOn(nameof(DateTimeModel))] 
 
     public DateTime CurrentDateTime => DateTimeModel.CurrentDateTime; 
 

 
     public MainViewModel() 
 
     { 
 
      DateTimeModel = new DateTimeModel(); 
 

 
      DateTimeModel.PropertyChanged += (s, e) => 
 
      { 
 
       Debug.WriteLine("DateTime PropertyChanged"); 
 
      }; 
 
     } 
 

 
     #region Events 
 

 
     public event PropertyChangedEventHandler PropertyChanged; 
 

 
     #endregion 
 

 
    } 
 
}

而一个DateTimeModel类,我用ThreadPoolTimer更新时间:

using System; 
 
using System.ComponentModel; 
 
using System.Diagnostics; 
 
using Windows.System.Threading; 
 
using Windows.UI.Core; 
 

 
namespace Logic.Ui.Models.DateTime 
 
{ 
 

 
    public class DateTimeModel : INotifyPropertyChanged 
 
    { 
 
     private ThreadPoolTimer _clockTimer; 
 

 
     public System.DateTime CurrentDateTime { get; set; } 
 
     
 
     public DateTimeModel() 
 
     { 
 
      _clockTimer = ThreadPoolTimer.CreatePeriodicTimer(ClockTimerTickAsync, TimeSpan.FromMilliseconds(1000)); 
 
     } 
 

 
     private async void ClockTimerTickAsync(ThreadPoolTimer timer) 
 
     { 
 
      await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,() => 
 
      { 
 
       CurrentDateTime = System.DateTime.Now; 
 
       Debug.WriteLine("Time updated"); 
 
      }); 
 

 
     } 
 

 
     #region Events 
 

 
     public event PropertyChangedEventHandler PropertyChanged; 
 

 
     #endregion 
 
    } 
 
}

的XAML代码如下所示:

<Page 
 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
 
    xmlns:local="using:MirrorV2.Ui.Raspberry" 
 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
 
    x:Class="MirrorV2.Ui.Raspberry.MainPage" 
 
    mc:Ignorable="d" 
 
    DataContext="{Binding Main, Source={StaticResource Locator}}"> 
 

 
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> 
 

 
     <TextBlock Text="{Binding CurrentDateTime}"/> 
 
     
 
    </Grid> 
 
</Page>

这里的问题是,用户界面没有更新,而的PropertyChanged事件beeing提高。 我在这里错过了什么?

编辑:如果我使用CurrentDateTime作为标准特性:

public DateTime CurrentDateTime { get; set; } 

,并在构造函数中分配当前日期时间的结合的作品。

CurrentDateTime = System.DateTime.Now; 

问题是MainViewModel.CurrentDateTime当你将MainViewModel.DateTimeModel,而不是当DateTimeModel的属性改变只得到通知。

This is a known Fody limitation和一个家伙here found a walkaround,让您在子属性的更改通知,像这样:

public class MainViewModel : ViewModelBase, INotifyPropertyChanged 
{ 

    // ... snip ... 

    [DependsOn(nameof(DateTimeModel))] 
    [DependsOn("DateTimeModel.CurrentDateTime")] 
    public DateTime CurrentDateTime => DateTimeModel.CurrentDateTime; 
} 

但我认为它更优雅砸MainViewModel.CurrentDateTime并绑定到MainViewModel.DateTimeModel直接

<TextBlock Text="{Binding DateTimeModel.CurrentDateTime}"/> 

这要求将DateTimeModel更改为属性,如mm8所示:

public DateTimeModel DateTimeModel { get; } 
+0

我已经使用了直接绑定 - 这是我最优雅的方式。谢谢。 – Christoph

抬起PropertyChanged事件,绑定到MainViewModelCurrentDateTime每当提出的DateTimeModelPropertyChanged事件:

public class MainViewModel : ViewModelBase, INotifyPropertyChanged 
{ 
    public DateTimeModel DateTimeModel; 

    [DependsOn(nameof(DateTimeModel))] 
    public DateTime CurrentDateTime => DateTimeModel.CurrentDateTime; 

    public MainViewModel() 
    { 
     DateTimeModel = new DateTimeModel(); 

     DateTimeModel.PropertyChanged += (s, e) => 
     { 
      Debug.WriteLine("DateTime PropertyChanged"); 
      this.RaisePropertyChanged(nameof(CurrentDateTime)); //<--- 
     }; 
    } 

    #region Events 
    public event PropertyChangedEventHandler PropertyChanged; 
    #endregion 
} 

或者你可以DateTimeModelMainViewModel类的属性:

public DateTimeModel DateTimeModel { get; private set; } 

...并直接绑定到在DateTimeModel的物业:你面对

<TextBlock Text="{Binding DateTimeModel.CurrentDateTime}"/>