【发布时间】:2018-11-04 13:17:30
【问题描述】:
我有一个简单的 WPF 窗口:Loaded="StartTest"
和
<Grid>
<ListBox ItemsSource="{Binding Logging, IsAsync=True}"></ListBox>
</Grid>
在我的方法StartTest后面的代码中:
LogModel LogModel = new LogModel();
void StartTest(object sender, RoutedEventArgs e)
{
DataContext = LogModel;
for (int i = 1; i<= 10; i++)
{
LogModel.Add("Test");
Thread.Sleep(100);
}
}
而LogModel 类是:
public class LogModel : INotifyPropertyChanged
{
public LogModel()
{
Dispatcher = Dispatcher.CurrentDispatcher;
Logging = new ObservableCollection<string>();
}
Dispatcher Dispatcher;
public ObservableCollection<string> Logging { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
public void Add(string text)
{
Dispatcher.BeginInvoke((Action)delegate ()
{
Logging.Add(text);
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Logging"));
});
}
}
当然,问题在于 UI 不会在循环中更新。
我错过了什么?
如何实现 UI 更新?
【问题讨论】:
-
在这种情况下设置
IsAsync=True是没有用的。 -
是的,我添加它是为了避免它作为建议的解决方案。
-
我实际上是想发布这个答案。抱歉:stackoverflow.com/a/20148603/7167572
-
在引入
async/await和异步数据绑定之前 使用了调度程序。您不需要无论如何都需要在 UI 线程上引发事件,View 的 工作是根据数据更新自身。由于您使用ObservableCollection,您根本不需要引发事件,它是由集合本身引发的。StartTest阻塞 UI 线程本身。反正奇怪的东西太多了 -
@Gerard 看起来你在某个时候遇到了障碍并开始抛出代码来“修复”它?你的初衷是什么?使用日志消息定期更新 UI?您可以使用只有一个
Logging属性的简单模型。只要StartTest没有阻塞,即没有Thread.Sleep,你就不应该有任何问题。请改用await Task.Delay()。顺便说一句,您是否将视图的上下文设置为模型?
标签: c# wpf user-interface dispatcher