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));
}
}
}
Pratik; 谢谢你的回复。我改变OnPropertyChanged()如你所说的落实,是的PropertyChanged仍然无效,即使在构造函数的调用: 内SelectedDateViewModel.OnPropertyChanged() SelectedDate =周四,2018年8月9日 的PropertyChanged为空:是 – ClockEndGooner
是你使用SelectedDateViewModel:INotifyPropertyChanged? – Pratik
是的,Pratik,我重写(复制/粘贴)OnPropertyChanged()的实现,并且PropertyChanged事件处理程序始终为null。我为这个麻烦道歉,但我错过了别的什么? – ClockEndGooner