作者:nicknick-AUG | 来源:互联网 | 2023-09-10 19:29
如何确保,ViewModel属性在再次更改它之前已经在视图上绑定了?有以下情况:ViewModel有一个变化非常快的对象。(通过不同的线程)View通过NotifyProperty
如何确保,ViewModel属性在再次更改它之前已经在视图上绑定了?
有以下情况: ViewModel
有一个变化非常快的对象。 (通过不同的线程)
View
通过NotifyPropertyChanged
接口获得通知,但它看起来很慢并且在View绑定新值并绘制之前它会更改次数因此它会错过某些值。
我还尝试将View
绑定到队列,然后ViewModel
可以将其排队, View
可以通过dequeueing绘制。
不幸的是发生了另一个问题:在RaisePropertyChanged(() => queue);
View
未被告知已更改。
在这种情况下, INotifyPropertyChanged
接口的实现不起作用。
你有什么主意吗?
ViewModel
示例代码:
public class ExamplaryViewModel { public ExamplaryViewModel() { Messenger.Default.Register(this, m => ProcessNotificationMessage(m.Content)); } public void ProcessNotificationMessage(Message message) { MessageOftenBeingChanged = message; RaisePropertyChanged(() => MessageOftenBeingChanged ); } }
View
绑定到MessageOftenBeingChanged
。
另一种选择是按照评论中的建议准备快照:
public void ProcessNotificationMessage(Message message) { Messages.Enqueue(message); RaisePropertyChanged(() => Messages); }
View
:
但是,不幸的是, RaisePropertyChanged()
方法不会触发发生的变化。
我计划在事件中控制OnQueueChangedChanged
尝试出列并只是绘制项目作为段落的新内联。
您可以实现Producer-Consumer 。
看看这个简化版本。
如果是空队列,您可以使用ManualResetMonitor
来避免不必要的迭代。
备注你的代码:
如果可以更改集合,那么出于绑定目的,您应该只使用ObservableCollection
(或实现INotifyCollectionChanged
东西),因为它跟踪更改并且不会重新加载所有内容。
但是在您的代码中,应该刷新整个绑定(因为您已通知整个集合已被更改),但我认为这种机制更智能并检查引用是否相等,如果是,则不进行刷新。 可能是一个hax将它设置为null
并返回将刷新它:-)。
通过许多调查我决定通过任何装饰器绑定到RichText框,带有额外DependencyProperty和Converter的自定义控件效率不高。
我的结论表明,构建自定义的richTextbox毫无价值 – 并确保在更改之前显示新值。
我辞职直接绑定。
我在缓冲区 – 队列中收集任何新消息。
我决定使用类似于消费者的东西(正如Wojciech Kulik建议的那样)
我将我的消费者基于TimeDispatcher,它在Tick的间隔中检查队列中是否存在任何新消息。 如果为真,那么它会出列并收集它,最后是RaiseMonitorItemsAdd。
查看事件上方的句柄:
if (dataContext is IMonitorable) { COntext= dataContext as IMonitorable; Context.MonitorViewModel.RaiseMonitorItemAdd += MonitorViewModelOnRaiseMonitorItemAdd; Context.MonitorViewModel.RaiseMonitorCleared += MonitorViewModel_RaiseMonitorCleared; } private void MonitorViewModelOnRaiseMonitorItemAdd(object sender, MonitorEventArgs monitorEventArgs) { Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => { _paragraph.Inlines.AddRange(MonitorItemConverter.ConvertToInlines(monitorEventArgs.MonitorItem)); _richTextBox.ScrollToEnd(); })); }
更多在RichTextBox获得许多项目的情况下,我将整个日志转储到文件。
上述就是C#学习教程:如何确保,ViewModel属性在再次更改它之前已经在视图上绑定了?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—编程笔记