为什么INotifyPropertyChanged的不更新在XAML中的变量?
-
21-08-2019 - |
题
我想模拟数据改变所述模型以及具有数据在XAML被反射。据我了解,我需要执行INotifyPropertyChanged。
然而,在下面的代码示例,XAML显示从顾客的数据仅一次,但日期和时间不会改变。
我有什么在下面的例子来改变,使XAML不断显示,因为它在模式改变了当前的日期和时间?
在特别的,我不明白是怎么绑定会知道什么时候检查模型,每一秒?每秒10次?没有任何事件,它是响应。缺少什么我在这里?
<强> XAML:强>
<Window x:Class="TestBinding99382.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TestBinding99382"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<ObjectDataProvider
x:Key="DataSourceCustomer"
ObjectType="{x:Type local:ShowCustomerViewModel}"
MethodName="GetCurrentCustomer"/>
</Window.Resources>
<DockPanel DataContext="{StaticResource DataSourceCustomer}">
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
<TextBlock Text="{Binding Path=FirstName}"/>
<TextBlock Text=" "/>
<TextBlock Text="{Binding Path=LastName}"/>
</StackPanel>
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
<TextBlock Text="{Binding Path=TimeOfMostRecentActivity}"/>
</StackPanel>
</DockPanel>
</Window>
<强>代码背后:强>
using System.Windows;
using System.ComponentModel;
using System;
namespace TestBinding99382
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
}
//view model
public class ShowCustomerViewModel : INotifyPropertyChanged
{
private Customer _currentCustomer;
public Customer CurrentCustomer
{
get
{
return _currentCustomer;
}
set
{
_currentCustomer = value;
this.RaisePropertyChanged("CurrentCustomer");
}
}
public ShowCustomerViewModel()
{
_currentCustomer = Customer.GetCurrentCustomer();
}
public Customer GetCurrentCustomer()
{
return _currentCustomer;
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
//model
public class Customer : INotifyPropertyChanged
{
private string _firstName;
private string _lastName;
private DateTime _timeOfMostRecentActivity;
public string FirstName
{
get
{
return _firstName;
}
set
{
_firstName = value;
this.RaisePropertyChanged("FirstName");
}
}
public string LastName
{
get
{
return _lastName;
}
set
{
_lastName = value;
this.RaisePropertyChanged("LastName");
}
}
public DateTime TimeOfMostRecentActivity
{
get
{
return _timeOfMostRecentActivity;
}
set
{
_timeOfMostRecentActivity = value;
this.RaisePropertyChanged("TimeOfMostRecentActivity");
}
}
public static Customer GetCurrentCustomer()
{
return new Customer
{ FirstName = "Jim"
, LastName = "Smith"
, TimeOfMostRecentActivity = DateTime.Now};
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
}
解决方案
也许我没有得到你希望这个代码做。
您已经创建了实现INotifyPropertyChanged一个Customer对象。您有另一个类,这是一个工厂的XAML去的实例。 现在,您创建具有预定义特性的客户实例。该视图显示它们。除非您更改属性不知何故,该视图将不会更新。
我添加了一个按钮将WPF视图
<Button DockPanel.Dock="Bottom"
x:Name="UpdateTime"
Click="UpdateTime_Click">
Update Activity Timestamp
</Button>
C#代码隐藏:
private void UpdateTime_Click(object sender, RoutedEventArgs e)
{
Customer.GetCurrentCustomer().TimeOfMostRecentActivity = DateTime.Now;
}
我也改变客户类型来创建用于当前顾客的单个实例
private static Customer _CurrentCustomer;
public static Customer GetCurrentCustomer()
{
if (null == _CurrentCustomer)
{
_CurrentCustomer = new Customer
{ FirstName = "Jim"
, LastName = "Smith"
, TimeOfMostRecentActivity = DateTime.Now
};
}
return _CurrentCustomer;
}
现在每次我点击该按钮时,DateTime
属性被修改和视图自动更新由于INotifyPropertyChanged
机制。该代码似乎是工作AFAISee。
其他提示
您的代码是否正常工作。当前日期和时间不会魔法自动更新。你必须实现某种计时器来更新它。
有关为例,你可以添加到您的Customer类:
private Timer _timer;
public Customer()
{
_timer = new Timer(UpdateDateTime, null, 0, 1000);
}
private void UpdateDateTime(object state)
{
TimeOfMostRecentActivity = DateTime.Now;
}
您似乎是结合Customer
,并Customer
的不的实施INotifyPropertyChanged
。尝试在INotifyPropertyChanged
实施Customer
,看看能否解决。这将需要在为了提高事件移动到手动性质(而不是自动实现的属性)。
您能查看GetCurrentCustomer()多少次被调用?也许它只是重新创建新实例的所有时间。
您的客户类需要实现INotifyPropertyChanged的,你需要在客户的属性的setter方法来调用事件。
修改:已经看过你再代码,我不知道你ShowCustomerViewModel类是否需要听取_currentCustomer PropertyChanged事件,并将它转发作为自己PropertyChangedEvent。值得一试。