通过单独的任务更新BindingSource中的元素
我有一个class,比如说人,有一个Id和一个免费精选名字大全。 该类正确实现了INotifyPropertyChanged
另外:有人要求上课人。
我真正的问题是一个更复杂的课程,我把它简化为一个相当简单的POCO,以确定它不是因为我的课程。
本来:
public class Person { public int Id {get; set;} public string Name {get; set;} }
对于更新,它需要实现INofityChanged。 完整的代码就在这个问题的最后
StackOverflow:如何正确实现INotifyPropertyChanged
到现在为止还挺好。 如果在单独的线程中更改Person,则会出现问题。
我经常收到带有消息的InvalidOperationException
BindingSource不能是自己的数据源。 不要将DataSource和DataMember属性设置为引用BindingSource的值。
我想这与更新是在一个等待的异步任务中完成的事实有关。 我知道在更新用户界面项之前,您应该检查InvokeRequired是否相应地采取行动。
private void OnGuiItemChanged() { if (this.InvokeRequired) { this.Invoke(new MethodInvoker(() => { OnGuiItemChanged(); })); } else { ... // update Gui Item } }
但是,使用绑定源时,更改将在bindingsource内处理。 所以我无法检查InvokeRequired
那么如何更新也存储在非UI线程中的绑定源中的项目?
按要求:类Person的实现和我的表单的一些代码
class Person : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private int id = 0; private string name = null; public int Id { get { return this.id; } set { this.SetField(ref this.id, value); } } public string Name { get { return this.name; } set { this.SetField(ref this.name, value); } } protected void SetField(ref T field, T value, [CallerMemberName] string propertyName = null) { if (!EqualityComparer.Default.Equals(field, value)) { field = value; RaiseEventPropertyChanged(propertyName); } } private void RaiseEventPropertyChanged(string propertyName) { var tmpEvent = this.PropertyChanged; if (tmpEvent != null) { tmpEvent(this, new PropertyChangedEventArgs(propertyName)); } } }
表格的一些代码:
private void Form1_Load(object sender, EventArgs e) { for (int i = 0; i ChangePersonsAsync(this.cancellationTokenSource.Token)); } private async Task ChangePersonsAsync(CancellationToken token) { try { while (!token.IsCancellationRequested) { foreach (var p in this.bindingSource1) { Person person = (Person)p; person.Id = -person.Id; } await Task.Delay(TimeSpan.FromSeconds(0.01), token); } } catch (TaskCanceledException) { } }
正如您所提到的,更改是在BindingSource
类中处理的,因此我看到的最简单方法是将其替换为以下内容
public class SyncBindingSource : BindingSource { private SynchronizationContext syncContext; public SyncBindingSource() { syncContext = SynchronizationContext.Current; } protected override void OnListChanged(ListChangedEventArgs e) { if (syncContext != null) syncContext.Send(_ => base.OnListChanged(e), null); else base.OnListChanged(e); } }
只要确保它是在UI线程上创建的。
上述就是C#学习教程:通过单独的任务更新BindingSource中的元素分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/989242.html