gpt4 book ai didi

c# - 在不同的线程中更新 CollectionView

转载 作者:太空宇宙 更新时间:2023-11-03 17:00:59 27 4
gpt4 key购买 nike

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

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

因为加载需要几秒钟,所以我尝试根据以下示例放置加载动画:

here

我想根据两个组合框过滤我的数据网格。

但是我有这个错误

This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread

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

我试过了

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

但我仍然有同样的错误。

View 模型

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

最佳答案

.Net 4.5 和更高版本中有一个非常好的方法来解决这个问题:

private object _lock = new object(); 

BindingOperations.EnableCollectionSynchronization("YourCollection", _lock);

因此,您无需在每次要操作集合时都使用 Dispatcher

这里有一些资源可以提供更多信息:

http://10rem.net/blog/2012/01/20/wpf-45-cross-thread-collection-synchronization-redux

BindingOperations.EnableCollectionSynchronization mystery in WPF

https://msdn.microsoft.com/en-us/library/hh198845%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396

关于c# - 在不同的线程中更新 CollectionView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33863877/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com