2017-09-13 77 views
0

簡單練習:在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; 

回答

2

問題是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

1

擡起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}"/>