我有一个带有 itemsSource 绑定(bind)的自定义控件:
private void OnItemsSourceChanged(IEnumerable oldValue, IEnumerable newValue)
{
Results.Clear();
foreach (var check in newValue)
{
Results.Add(check as Check);
}
}
protected ObservableCollection<Check> results = new ObservableCollection<Check>();
public ObservableCollection<Check> Results
{
get { return results; }
set { results = value; }
}
在主视图中实现:
<control:ResultCtrl x:Name="resultCtrl" ItemsSource="{Binding Path=Results, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}"></control:ResultCtrl>
检查类:
public class Check : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected string checkStateString;
public string CheckStateString
{
get { return checkStateString; }
set
{
if (value != checkStateString)
{
checkStateString = value;
if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("CheckStateString"));
}
}
}
我在主视图 show 方法中调用一个计算支票的类:
Thread t = new Thread(new ThreadStart(
delegate
{
Dispatcher.Invoke(DispatcherPriority.Normal, new Action<ResultCtrl>(AddIn.Services.Results.Comprobaciones), resultCtrl);
}
));
t.Start();
在 AddIn.Services.Results.Comprobaciones 中我这样做:
resultCtrl.ItemsSource = new ObservableCollection<Check>(AddIn.Document.Results);
每张支票。每次我这样做时,我都会看到 ItemsSource 如何变化,但 Visual 仅在 AddIn.Services.Results.Comprobaciones 结束时更新。我尝试执行 UpdateLayout() 和 Items.Refresh() 但没有任何效果。
有什么想法吗?
最佳答案
这段代码:
Thread t = new Thread(new ThreadStart(/* ... */);
t.Start();
创建一个完全无用的线程,因为它所做的一切都是对 UI 线程的 Dispatcher
的阻塞调用。换句话说,它有 99.999...% 的时间在 UI 线程上运行。你可以很容易地这样写:
AddIn.Services.Results.Comprobaciones();
同样的结果。
您必须重写代码才能从多线程中获益。我不知道您的 Comprobaciones
方法是什么样的,但是,显然,您应该仅在需要更新 UI 中的内容时才调用 Dispatcher.Invoke
。
另请注意,在大多数情况下,您不应直接创建 Thread
实例。考虑使用 TPL相反(如果您的目标是 .NET 4.5,可能通过 async
/await
)。
关于c# - Wpf ItemSsource 不更新自定义控件中的视觉控件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24802863/