Xamarin.Forms&MVVM在C#中:PropertyChanged事件处理程序总是空时OnPropertyChanged被称为

问题描述:

我写了一个简单的应用程序在C#中使用Xamarin.Forms与Visual Studio 2017,并有一个数据绑定工作来更新内容的问题标签子控件的显示DatePicker子控件在同一个ContentPage中选定的日期值。尽管所有的项目元素编译,构建和部署都没有任何错误,并且每次在DatePicker中选择日期时都会调用ViewModel中的OnPropertyChanged方法,但是当PropertyChanged事件处理程序中的PropertyChanged事件处理程序始终为空对象引用时OnPropertyChanged方法被调用,并且不会按照预期的方式使用新的选定日期值更新Label的Text属性的内容。Xamarin.Forms&MVVM在C#中:PropertyChanged事件处理程序总是空时OnPropertyChanged被称为

以下是我的MainPage实现,除了支持ViewModel类SelectedDateViewModel.cs。

C#[MainPage.xaml.cs中]

using System; 
using Xamarin.Forms; 

namespace DataBoundDatePicker 
{ 
    public partial class MainPage : ContentPage 
    { 
     public MainPage() 
     { 
      InitializeComponent(); 

      BindingContext = new SelectedDateViewModel(); 
     } 
    } 
} 

XAML [MainPage.xaml中]

<?xml version="1.0" encoding="utf-8" ?> 
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
      xmlns:local="clr-namespace:DataBoundDatePicker" 
      x:Class="DataBoundDatePicker.MainPage"> 
    <StackLayout Padding="20" VerticalOptions="Center" HorizontalOptions="Center"> 
     <Label Text="Data Bound DatePicker" FontAttributes="Bold" HorizontalOptions="Center" /> 
     <Label Text="Select a Date:" /> 
     <DatePicker x:Name="SelectedDatePicker" Date="{Binding SelectedDate}"/> 
     <StackLayout Orientation="Horizontal"> 
      <Label Text="Formatted Date:" /> 
      <Label x:Name="FormattedDateLabel" Text="{Binding SelectedDate, StringFormat='{0:dddd, MMMM d, yyyy}'}" /> 
     </StackLayout> 
    </StackLayout> 
</ContentPage> 

C#[SelectedDateViewModel.cs]

using System; 
using System.ComponentModel; 
using System.Diagnostics; 

namespace DataBoundDatePicker 
{ 
    public class SelectedDateViewModel 
    { 
     private readonly string FullDateFormat = "dddd, MMMM d, yyyy"; 

     private DateTime selectedDate; 

     public event PropertyChangedEventHandler PropertyChanged; 

     public SelectedDateViewModel() 
     { 
      Debug.WriteLine("Entering SelectedDateViewModel.SelectedDateViewModel() - Constructor"); 

      SelectedDate = DateTime.Now; 

      Debug.WriteLine("Leaving SelectedDateViewModel.SelectedDateViewModel() - Constructor"); 
     } 

     public DateTime SelectedDate 
     { 
      get 
      { 
       return selectedDate; 
      } 

      set 
      { 
       if (selectedDate != value) 
       { 
        selectedDate = value; 
        OnPropertyChanged("SelectedDate"); 
       } 
      } 
     } 

     protected virtual void OnPropertyChanged(string propertyName) 
     { 
      Debug.WriteLine("Inside SelectedDateViewModel.OnPropertyChanged()"); 

      Debug.WriteLine($"SelectedDate = {selectedDate.ToString(FullDateFormat)}"); 

      var trace = 
      $"PropertyChanged Is Null: {(PropertyChanged == null ? "Yes" : "No")}"; 
      Debug.WriteLine(trace); 

      var propertyChangedCallback = PropertyChanged; 
      propertyChangedCallback?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

当前实现执行以下操作:

  • 在启动时,FormattedDateLabel显示正确的格式基于 SelectedDateViewModel的SelectedDate的DateTime属性 日期字符串。但是,对SelectedDatePicker控件中Date 属性的任何后续更改。

  • 没有失败,每一次的日期值在 SelectedDatePicker控制改变时, SelectedDateViewModel.OnPropertyChanged()方法被调用总是, 甚至通过的MainPage的实例化和 SelectedDateViewModel对象实例启动(如构造函数调用)。

  • 虽然SelectedDateViewModel.OnPropertyChanged()的日期值中的DatePicker改变时调用的任何 时间, SelectedDateViewModel的PropertyChanged事件的参考始终是 空,甚至在启动时(同样,当通过构造函数调用 实例化) 。这被示出具有发射作为该程序的下面的调试跟踪语句 在调试模式通过Visual Studio中 运行:

'DataBoundDatePicker.UWP.exe'(CoreCLR:CoreCLR_UWP_Domain):加载 “C :\工作\ Xamarin \ DataBoundDatePicker \ DataBoundDatePicker \ DataBoundDatePicker.UWP \ BIN \ 86 \调试\ AppX中\ Xamarin.Forms.Xaml.dll”。 跳过加载符号。模块已经过优化,调试器选项 “Just My Code”已启用。 输入MainPage.MainPage() - 构造函数 输入SelectedDateViewModel.SelectedDateViewModel() - 构造函数 Inside SelectedDateViewModel。OnPropertyChanged() SelectedDate =周二,2017年7月4日 的PropertyChanged为空:是 离开SelectedDateViewModel.SelectedDateViewModel() - 构造 离开MainPage.MainPage() - 构造 线程0x1630已退出,代码为0(为0x0)。 内SelectedDateViewModel.OnPropertyChanged() SelectedDate =星期日,2012年3月4日 的PropertyChanged为空:是

  • 的代码表现出相同的行为,不管部署和调试 的UWP的或Android版应用。

任何帮助或洞察力和解释,你可以在我怎样才能得到Text属性有其Text属性绑定到使用视图模型,其中PropertyChanged事件是不是空引用,将不胜感激的 日期财产份额。

预先感谢您的时间和帮助。

使用INotifyPropertyChanged接口。喜欢这个。

public class SelectedDateViewModel : INotifyPropertyChanged 
    { 
     private readonly string FullDateFormat = "dddd, MMMM d, yyyy"; 

     private DateTime selectedDate; 

     public event PropertyChangedEventHandler PropertyChanged; 

     public SelectedDateViewModel() 
     { 
      Debug.WriteLine("Entering SelectedDateViewModel.SelectedDateViewModel() - Constructor"); 

      SelectedDate = DateTime.Now; 

      Debug.WriteLine("Leaving SelectedDateViewModel.SelectedDateViewModel() - Constructor"); 
     } 

     public DateTime SelectedDate 
     { 
      get 
      { 
       return selectedDate; 
      } 

      set 
      { 
       if (selectedDate != value) 
       { 
        selectedDate = value; 
        OnPropertyChanged("SelectedDate"); 
       } 
      } 
     } 

     protected virtual void OnPropertyChanged(string propertyName) 
     { 
      if (PropertyChanged != null) 
      { 
        PropertyChanged(this, 
         new PropertyChangedEventArgs(propertyName)); 
      } 
     } 
    } 
+0

Pratik; 谢谢你的回复。我改变OnPropertyChanged()如你所说的落实,是的PropertyChanged仍然无效,即使在构造函数的调用: 内SelectedDateViewModel.OnPropertyChanged() SelectedDate =周四,2018年8月9日 的PropertyChanged为空:是 – ClockEndGooner

+0

是你使用SelectedDateViewModel:INotifyPropertyChanged? – Pratik

+0

是的,Pratik,我重写(复制/粘贴)OnPropertyChanged()的实现,并且PropertyChanged事件处理程序始终为null。我为这个麻烦道歉,但我错过了别的什么? – ClockEndGooner