在不同的线程中更新CollectionView

坎蒂努

我正在开发我的第一个WPF浏览器应用程序。

我将发票加载到dataGrid中,然后使用textBox或comboBox进行过滤。

由于加载需要花费几秒钟的时间,因此我尝试根据以下示例放置加载动画:

这里

我想根据两个comboBox过滤我的dataGrid。

但是我有这个错误

这种类型的CollectionView不支持从与Dispatcher线程不同的线程对其SourceCollection进行更改

在该行中invoiceCollection.Clear();invoiceCollection.Add(inv);在SearchFilter()中;

我试过

App.Current.Dispatcher.Invoke((Action)delegate // <--- HERE
{
    //code here
});

但我仍然有同样的错误。

视图模型

public class ConsultInvoiceViewModel : ViewModelBase
{
      public Context ctx = new Context();

      private ICollectionView _dataGridCollection;
      private ObservableCollection<Invoice> invoiceCollection;


      public ConsultInvoiceViewModel()
      {
        if (!WPFHelper.IsInDesignMode)
        {
            var tsk = Task.Factory.StartNew(InitialStart);
            tsk.ContinueWith(t => { MessageBox.Show(t.Exception.InnerException.Message); }, CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, TaskScheduler.FromCurrentSynchronizationContext());
            }
        }

     private void InitialStart()
     {
         try
         {
          State = StateEnum.Busy;
          DataGridCollection = CollectionViewSource.GetDefaultView(Get());
          DataGridCollection.Filter = new Predicate<object>(Filter);
          }
          finally
          {
          State = StateEnum.Idle;
          }
     }

      private void SearchFilter()
      {

                                Task tsk = Task.Factory.StartNew(()=>
                                                                    {
                                         try
                                            {
                                             State = StateEnum.Busy;
                                             using (var ctx = new Context())
                                             {

                                                  var invs = ctx.Invoices
                                                             .Where(s.supplier == 1)
                                                             .GroupBy(x => new { x.suppInvNumber, x.foodSupplier })
                                                             .ToList()
                                                             .Select(i => new Invoice
                                                                          {
                                                                           suppInvNumber = i.Key.suppInvNumber,
                                                                           foodSupplier = i.Key.foodSupplier,
                                                                           totalPrice = i.Sum(t => t.totalPrice),
                                                                           });
                                                             .

                                            App.Current.Dispatcher.Invoke((Action)delegate 
                                           {
                                                invoiceCollection.Clear();
                                            });

                                                if (invs != null)
                                                       foreach (var inv in invs)
                                                       {
                                                            App.Current.Dispatcher.Invoke((Action)delegate  
                                                            {
                                                            invoiceCollection.Add(inv);
                                                            });

                                                       }
                                             }
                                             }
                                             finally
                                             {
                                              State = StateEnum.Idle;
                                             }

                    });
                                tsk.ContinueWith(t => { MessageBox.Show(t.Exception.InnerException.Message); }, CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, TaskScheduler.FromCurrentSynchronizationContext());
                            }

    public static readonly PropertyChangedEventArgs StateArgs = ViewModelBase.CreateArgs<ConsultInvoiceViewModel>(c => c.State);
    private StateEnum _State;

    public StateEnum State
    {
       get
       {
           return _State;
       }
       set
       {
            var oldValue = State;
            _State = value;
            if (oldValue != value)
            {
                 OnStateChanged(oldValue, value);
                 OnPropertyChanged(StateArgs);
            }
       }
    }

    protected virtual void OnStateChanged(StateEnum oldValue, StateEnum newValue)
    {
    }

}  

ViewModelBase

public abstract class ViewModelBase : INotifyPropertyChanged
{
    #region "INotifyPropertyChanged members"

    public event PropertyChangedEventHandler PropertyChanged;
    //This routine is called each time a property value has been set. 
    //This will //cause an event to notify WPF via data-binding that a change has occurred. 
    protected void OnPropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    #endregion

    public void OnPropertyChanged(PropertyChangedEventArgs args)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, args);
    }

    public static PropertyChangedEventArgs CreateArgs<T>(Expression<Func<T, Object>> propertyExpression)
    {
        return new PropertyChangedEventArgs(GetNameFromLambda(propertyExpression));
    }

    private static string GetNameFromLambda<T>(Expression<Func<T, object>> propertyExpression)
    {
        var expr = propertyExpression as LambdaExpression;
        MemberExpression member = expr.Body is UnaryExpression ? ((UnaryExpression)expr.Body).Operand as MemberExpression : expr.Body as MemberExpression;
        var propertyInfo = member.Member as PropertyInfo;
        return propertyInfo.Name;
    }
}
坎蒂努

我终于可以正常工作了。这很简单。

public class ConsultInvoiceViewModel : ViewModelBase
    {

      public Context ctx = new Context();

      private ICollectionView _dataGridCollection;
      private ObservableCollection<Invoice> invoiceCollection;


      public ConsultInvoiceViewModel()
      {
        invoiceCollection = new ObservableCollection<Invoice>();
        DataGridCollection = CollectionViewSource.GetDefaultView(Get());        

        if (!WPFHelper.IsInDesignMode)
        {
            var tsk = Task.Factory.StartNew(InitialStart);
            tsk.ContinueWith(t => { MessageBox.Show(t.Exception.InnerException.Message); }, CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, TaskScheduler.FromCurrentSynchronizationContext());
            }
        }

     private void InitialStart()
     {
         try
         {
          State = StateEnum.Busy;
          Get();
          }
          finally
          {
          State = StateEnum.Idle;
          }
     }

      private void SearchFilter()
      {

                                Task tsk = Task.Factory.StartNew(()=>
                                                                    {
                                         try
                                            {
                                             State = StateEnum.Busy;
                                             using (var ctx = new Context())
                                             {

                                                  var invs = ctx.Invoices
                                                             .Where(s.supplier == 1)
                                                             .GroupBy(x => new { x.suppInvNumber, x.foodSupplier })
                                                             .ToList()
                                                             .Select(i => new Invoice
                                                                          {
                                                                           suppInvNumber = i.Key.suppInvNumber,
                                                                           foodSupplier = i.Key.foodSupplier,
                                                                           totalPrice = i.Sum(t => t.totalPrice),
                                                                           });
                                                             .

                                            App.Current.Dispatcher.Invoke((Action)delegate 
                                           {
                                                invoiceCollection.Clear();
                                                if (invs != null)
                                                       foreach (var inv in invs)
                                                       {
                                                     invoiceCollection.Add(inv);
                                                       }
                                            });


                                             }
                                             }
                                             finally
                                             {
                                              State = StateEnum.Idle;
                                             }

                    });
                                tsk.ContinueWith(t => { MessageBox.Show(t.Exception.InnerException.Message); }, CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, TaskScheduler.FromCurrentSynchronizationContext());
                            }

        private ObservableCollection<Invoice> Get()
        {

            using (var ctx = new Context())
            {
                var invs = ctx.Invoices

                foreach (var inv in invs)
                {
                   App.Current.Dispatcher.Invoke((Action)delegate 
                   {
                       invoiceCollection.Add(inv);
                   });
                }
            }

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

从JavaFX中的不同线程更新UI

来自分类Dev

WPF中拥有不同的线程

来自分类Dev

在不同的线程中创建QApplication

来自分类Dev

从后台线程和线程中的线程更新UI

来自分类Dev

如何从线程中调用与run()不同的方法

来自分类Dev

Java中的线程与C ++中的线程是否不同?

来自分类Dev

线程中的位置更新

来自分类Dev

不同线程中SharedPreference的访问值

来自分类Dev

在不同的线程中更新CollectionView

来自分类Dev

CUDA中不同块内的线程差异

来自分类Dev

从不同线程更新AbstractTableModel

来自分类Dev

Tkinter GUI中的多线程,不同类中的线程

来自分类Dev

更新到Retrofit 2.0后,PublishSubject的onNext调用在不同的线程中

来自分类Dev

QSqlDatabase不同线程中的并发查询

来自分类Dev

在不同的线程中执行每个QTModbus响应

来自分类Dev

多线程:如何在不同的线程中运行不同的功能?

来自分类Dev

线程lambda中的原子更新

来自分类Dev

xamarin在CollectionView中形成更新项

来自分类Dev

WPF中拥有不同的线程

来自分类Dev

在asynctask中更新UI线程

来自分类Dev

Java中不同类对象的线程

来自分类Dev

在UicollectionViewCell中更新CollectionView的大小

来自分类Dev

从单独的线程中更新标签

来自分类Dev

从后台线程和线程中的线程更新UI

来自分类Dev

如何从线程中调用与run()不同的方法

来自分类Dev

在不同线程中运行任务

来自分类Dev

通过不同的线程更新Java UI

来自分类Dev

QSqlDatabase不同线程中的并发查询

来自分类Dev

mvvm backgroundworker - CollectionView 不支持从不同于 Dispatcher 线程的线程更改其 SourceCollection