Wpf ItemSsource不能#39;在自定义控件中更新Visual Control

时间:2014-07-17 11:55:47

标签: c# wpf

我有一个带有itemsSource绑定的自定义控件:

    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"));
            }
        }
    }

我打电话给在Main View 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()但没什么用。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

此代码:

Thread t = new Thread(new ThreadStart(/* ...  */);
t.Start();

创建一个完全没用的线程,因为它所做的一切都是对UI线程Dispatcher的阻塞调用。换句话说,它在UI线程上运行的时间为99.999%。你可以轻松地写下这个:

AddIn.Services.Results.Comprobaciones();

具有相同的结果。

您必须重写代码才能从多线程中获益。我不知道,您的Comprobaciones方法看起来如何,但显然,只有当您需要在UI中更新某些内容时,才应调用Dispatcher.Invoke

另请注意,在大多数情况下,您不应直接创建Thread个实例。如果您要定位.NET 4.5,请考虑使用TPL代替(可能通过async / await。)