4

我想模拟模型中的数据更改并将该数据反映在 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));
            }
        }
    }
}
4

5 回答 5

4

也许我没有得到你希望这段代码做的事情。

您已经创建了一个实现 INotifyPropertyChanged 的​​客户对象。您有另一个类,它是 XAML 获取实例的工厂。现在,您创建一个具有预定义属性的 Customer 实例。视图显示它们。除非您以某种方式更改属性,否则视图将不会更新。

我在您的 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。

于 2009-05-12T08:26:06.833 回答
3

您的代码工作正常。当前日期和时间不会被魔法自动更新。您必须实现一些计时器来更新它。

例如,您可以将其添加到您的客户类中:

private Timer _timer;

public Customer()
{
    _timer = new Timer(UpdateDateTime, null, 0, 1000);
}

private void UpdateDateTime(object state)
{
    TimeOfMostRecentActivity = DateTime.Now;
}
于 2009-05-12T08:06:23.277 回答
0

您似乎绑定到Customer,并且Customer 没有实现INotifyPropertyChanged。尝试实施INotifyPropertyChangedon Customer,看看是否可以解决它。这将需要移动到手动属性(而不是自动实现的属性)以引发事件。

于 2009-05-12T07:42:18.917 回答
0

您的客户类需要实现 INotifyPropertyChanged,并且您需要在客户属性的 setter 方法期间调用该事件。

编辑:再次查看了您的代码,我想知道您的 ShowCustomerViewModel 类是否需要侦听 _currentCustomer PropertyChanged 事件并将其作为自己的 PropertyChangedEvent 转发。值得一试。

于 2009-05-12T07:44:01.397 回答
0

你能检查 GetCurrentCustomer() 被调用了多少次吗?也许它只是一直在重新创建新实例。

于 2009-05-12T07:56:49.020 回答