【问题标题】:Load ICollectionView With Task Library使用任务库加载 ICollectionView
【发布时间】:2014-07-14 13:11:04
【问题描述】:

我有以下问题: 如果我将一个简单的列表加载到绑定在我的 wpf 列表框上的 ICollectionView 中,那么 CurrentChanged 事件会按我的预期引发:

List<int> l = new List<int>();
l.Add(1);
l.Add(2);
MyCollection = CollectionViewSource.GetDefaultView(l);
MyCollection.CurrentChanged += MyCollection_CurrentChanged; // ok, it's raised

但是,假设我正在将数据加载到另一个线程中,然后,我想要相同的行为,即引发 currentChanged 事件,但它不起作用:

 List<int> l = new List<int>();
            Task.Factory.StartNew(() =>
            {
                l.Add(1);
                l.Add(2);
            })
            .ContinueWith((r) => 
                {

                    MyCollectio = CollectionViewSource.GetDefaultView(l);
                    MyCollectio.CurrentChanged += MyCollectio_CurrentChanged; // ko, it isn't raised.

                }, TaskScheduler.FromCurrentSynchronizationContext());

请注意,我正在使用 TaskScheduler.FromCurrentSynchronizationContext() 来处理 UI 线程,但它不起作用。我也尝试过 Application.Current.Dispatcher.Invoke 没有运气。

【问题讨论】:

  • 您使用的是哪个版本的 .net 框架?

标签: wpf multithreading icollectionview


【解决方案1】:

我认为根本原因在于您的 xaml。

如果您使用的是从Selector 继承的<ListBox /> 或任何其他ItemsControl,请尝试将IsSynchronizedWithCurrentItem 设置为True,如下所示:

<ListBox ItemsSource="{Binding MyCollectio}"
         IsSynchronizedWithCurrentItem="True"
         />

我已经尝试过了,不管有没有TPL Task,它都可以正常工作

在 MainWindow.xaml.cs 我有这个(试试看,xaml 应该包含上面提到的 ListBox):

public MainWindow()
{
    InitializeComponent();

    MyVM con = new MyVM();
    DataContext = con;
    List<int> l = new List<int>();
    Task.Factory.StartNew(() =>
    {
        l.Add(1);
        l.Add(2);
        l.Add(3);
        l.Add(4);
        l.Add(5);
        l.Add(6);
    })
    .ContinueWith((r) =>
    {

        con.MyCollectio = CollectionViewSource.GetDefaultView(l);
        con.MyCollectio.CurrentChanged += MyCollectio_CurrentChanged;
    }, TaskScheduler.FromCurrentSynchronizationContext());
}

void MyCollectio_CurrentChanged(object sender, EventArgs e)
{
    MessageBox.Show("Curren really changed!!!");
}

...

public class MyVM : ViewModelBase
{
    public ICollectionView MyCollectio
    {
        get
        {
            return _MyCollectio;
        }

        set
        {
            _MyCollectio = value;
            RaisePropertyChanged("MyCollectio");
        }
    }
    private ICollectionView _MyCollectio;
}

...

public class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public void RaisePropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

【讨论】:

  • 我已经将 IsSynchronizedWithCurrentItem 设置为 true,但是就像我的代码 sn-p 一样,它不起作用。我正在使用 Visual Studio 2012 和 .NET Frameork 4.0
  • 我刚刚使用了您的代码,正如我所料,它不起作用。现在我将 VS 2013 与 .NET 4.5 一起使用。这似乎是不可能的!
  • 我已经通过用 TaskScheduler.Current 替换 TaskScheduler.FromCurrentSynchronizationContext()) 解决了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-30
  • 2019-06-15
  • 1970-01-01
  • 2020-07-31
  • 2015-02-01
  • 1970-01-01
相关资源
最近更新 更多