0

I've the following problem: if I load a simple list into ICollectionView which is bound on my wpf listbox, then CurrentChanged event being raised as I expected:

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

However, Imagine I'm loading data into another thread, then, I would like the same behaviors, that is raising currentChanged event, but it doesn't work:

 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());

Note that I'm using TaskScheduler.FromCurrentSynchronizationContext() in order to work on UI thread, however it doesn't work. I also tried with Application.Current.Dispatcher.Invoke without luck.

4

1 回答 1

0

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

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

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

我已经尝试过了,无论有没有TPL 任务,它都可以正常工作

在 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));
    }
}
于 2014-07-14T16:06:04.160 回答