我在 ViewModel 中使用 DispatchTimer 在模型上引发 OnPropertyChanged,但模型不会在 UI 中更新,除非我引用模型的“TimeSpan”属性。
视图中的 TextBlock 每毫秒更新一次,以显示 TimeSpan 的增加,但 TestUserControl 不会更新。
视图模型
公共类 TestViewModel:ViewModelBase { 公共DispatcherTimer_timer; 公共测试视图模型() { Test1 = new TestObject(); Test1.Name = "测试名称"; Test1.DateTime = DateTime.Now; _timer = new DispatcherTimer(DispatcherPriority.Render); _timer.Interval = TimeSpan.FromMilliseconds(1); _timer.Tick += (发送者, args) => { OnPropertyChanged(nameof(测试)); }; _timer.Start(); } 私有测试对象测试1; 公共测试对象测试1 { 得到 { 返回测试1; } 放 { 测试1=值; OnPropertyChanged(nameof(Test1)); } } }
型号
公共类测试对象 { 公共字符串名称{获取;放; } 公共日期时间日期时间{获取;放; } 公共 TimeSpan TimeSpan => DateTime.Now - DateTime; }
查看
<StackPanel>
<userControls:TestUserControl DataContext="{Binding Test1}"/>
<TextBlock Text="{Binding Test1.TimeSpan}"/> //updating on UI
</StackPanel>
测试用户控件
<StackPanel>
<TextBlock Text="{Binding Name}"/> //shows initial value
<TextBlock Text="{Binding TimeSpan}"/> //shows initial value and does not update
<StackPanel>
也许可以从在您的
INotifyPropertyChanged
模型中实现 TestObject
开始。然后,当我实际运行你的代码时,似乎这可能就是你想要的?
public partial class MainWindow : Window
{
public MainWindow()
{
DataContext = new TestViewModel();
InitializeComponent();
}
}
public class TestViewModel : ViewModelBase
{
public DispatcherTimer _timer;
public TestViewModel()
{
Test1 = new TestObject();
Test1.Name = "TestName";
_timer = new DispatcherTimer(DispatcherPriority.Render);
_timer.Interval = TimeSpan.FromSeconds(1);
_timer.Tick += (sender, args) =>
{
Test1.TimeSpan = DateTime.Now - Test1.DateTimeInit;
};
_timer.Start();
}
private TestObject test1;
public TestObject Test1
{
get
{
return test1;
}
set
{
test1 = value;
OnPropertyChanged(nameof(Test1));
}
}
}
public class TestObject : INotifyPropertyChanged
{
public string Name
{
get => _name;
set
{
if (!Equals(_name, value))
{
_name = value;
OnPropertyChanged();
}
}
}
string _name = string.Empty;
public DateTime DateTimeInit { get; } = DateTime.Now;
public TimeSpan TimeSpan
{
get => _timeSpan;
set
{
if (!Equals(_timeSpan, value))
{
_timeSpan = value;
OnPropertyChanged();
}
}
}
TimeSpan _timeSpan = default;
private void OnPropertyChanged([CallerMemberName] string? propertyName = null) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
public event PropertyChangedEventHandler? PropertyChanged;
}
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}