- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一个实现 INotifyPropertyChanged
的基类:
protected void OnNotifyChanged(string pName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(pName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
我有一个派生类,其属性 Latitude
如下所示:
private double latitude;
public double Latitude
{
get { return latitude; }
set { latitude = value; OnNotifyChanged("Latitude"); }
}
我的派生类还有一个方法 Fly
可以操作 Latitude
。
我还有一个带有绑定(bind)到派生类的 Latitude
的 TextBox 的表单:
txtLat.DataBindings.Clear();
txtLat.DataBindings.Add("Text", bindSrc, "Latitude");
线程用于启动 Fly
,如下所示:
Thread tFly = new Thread(f.Fly);
tFly.IsBackground = true;
tFly.Start();
当 Latitude
改变时,抛出异常:
DataBinding 在列表中找不到适合所有绑定(bind)的行。
最佳答案
这似乎是线程亲和性的一个奇怪问题。最终,代码试图从非 UI 线程进行更新——我不清楚为什么它不只是显示跨线程异常——我想知道这是否实际上是一个包罗万象的异常处理程序。如果我删除 BindingSource
(并直接绑定(bind)到有效的对象),您会得到一个跨线程异常(这是我预料到的)。
个人,我倾向于手动处理,即使用对 UI 线程执行 Invoke
并更新 的方法订阅事件文本
手动。但是,我只是在检查一些以前的跨线程绑定(bind)代码是否有帮助...
这是一个使用 Invoke
的例子:
using System;
using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;
class FlightUav : INotifyPropertyChanged
{
protected void OnNotifyChanged(string pName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(pName));
}
public event PropertyChangedEventHandler PropertyChanged;
private double _latitude;
public double Latitude
{
get { return _latitude; }
set { _latitude = value; OnNotifyChanged("Latitude"); }
}
public void Fly()
{
for (int i = 0; i < 100; i++)
{
Latitude++;
Thread.Sleep(10);
}
}
[STAThread]
static void Main()
{
using (Form form = new Form())
{
FlightUav currentlyControlledFlightUav = new FlightUav();
currentlyControlledFlightUav.PropertyChanged += delegate
{ // this should be in a *regular* method so that you can -= it when changing bindings...
form.Invoke((MethodInvoker)delegate
{
form.Text = currentlyControlledFlightUav.Latitude.ToString();
});
};
using (Button btn = new Button())
{
btn.Text = "Fly";
btn.Click += delegate
{
Thread tFly = new Thread(currentlyControlledFlightUav.Fly);
tFly.IsBackground = true;
tFly.Start();
};
form.Controls.Add(btn);
Application.Run(form);
}
}
}
}
这是一个使用我的一些旧线程代码的(修改)版本的示例:
using System;
using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;
class FlightUav : INotifyPropertyChanged
{
protected void OnNotifyChanged(string pName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(pName));
}
public event PropertyChangedEventHandler PropertyChanged;
private double _latitude;
public double Latitude
{
get { return _latitude; }
set { _latitude = value; OnNotifyChanged("Latitude"); }
}
public void Fly()
{
for (int i = 0; i < 100; i++)
{
Latitude++;
Thread.Sleep(10);
}
}
[STAThread]
static void Main()
{
using (Form form = new Form())
{
FlightUav currentlyControlledFlightUav = new FlightUav();
BindingSource bindSrc = new BindingSource();
var list = new ThreadedBindingList<FlightUav>();
list.Add(currentlyControlledFlightUav);
bindSrc.DataSource = list;
form.DataBindings.Clear();
form.DataBindings.Add("Text", list, "Latitude");
using (Button btn = new Button())
{
btn.Text = "Fly";
btn.Click += delegate
{
Thread tFly = new Thread(currentlyControlledFlightUav.Fly);
tFly.IsBackground = true;
tFly.Start();
};
form.Controls.Add(btn);
Application.Run(form);
}
}
}
}
public class ThreadedBindingList<T> : BindingList<T>
{
private readonly SynchronizationContext ctx;
public ThreadedBindingList()
{
ctx = SynchronizationContext.Current;
}
protected override void OnAddingNew(AddingNewEventArgs e)
{
SynchronizationContext ctx = SynchronizationContext.Current;
if (ctx == null)
{
BaseAddingNew(e);
}
else
{
ctx.Send(delegate
{
BaseAddingNew(e);
}, null);
}
}
void BaseAddingNew(AddingNewEventArgs e)
{
base.OnAddingNew(e);
}
protected override void OnListChanged(ListChangedEventArgs e)
{
if (ctx == null)
{
BaseListChanged(e);
}
else
{
ctx.Send(delegate
{
BaseListChanged(e);
}, null);
}
}
void BaseListChanged(ListChangedEventArgs e)
{
base.OnListChanged(e);
}
}
关于c# - INotifyPropertyChanged 和线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4825225/
我在我的 LINQ-to-SQL 类中修改了我的数据源(通过旧的删除和拖回方法),并且惊讶地看到 INotifyPropertyChanging 和 INotifyPropertyChanged 接口
我喜欢对需要 INotifyPropertyChanged 接口(interface)的完整属性进行一些较少重复和浪费的编码,并进行自定义属性。 背景 今天,为了在窗口中使用具有动态更新值的 MVVM
INotifyPropertyChanged 的目的是什么。我知道每当更改属性时都会触发此事件,但是 View /用户界面如何知道触发了此事件: 这是实现 INotifyPropertyChang
我已经设置了一个属性并实现了 INotifyPropertyChanged 像这样... public event PropertyChangedEventHandler PropertyChange
我有一个类(我们称它为 MyContainerClass ),它是其他几个类的容器(我们称它们为 ClassA 到 ClassF )。 ClassA至ClassF继承相同的基类(我们称之为 MyBas
鉴于: public class MyClass : INotifyPropertyChanged { public List _TestFire = new List(); stri
首先,我想说下面的示例过于简单化。 假设您已绑定(bind) WPF 控件。 Window 绑定(bind)到实现 INotifyPro
我想将窗口中的 TextBox 绑定(bind)到作为 View 模型变量的类中包含的属性,并确保 INotifyPropertyChanged 的 PropertyChanged 事件从类传播到
所有使用 MVVM 的 Silverlight 示例都使用名为 IPropertyChanged 的接口(interface)。它背后的概念是什么,为什么我们需要在设置一些值时引发事件? 例如:-
我正在阅读最新的Prism 4发行版的源代码,并且对解决此问题感兴趣。 ViewModels有一个基类,它实现INotifyPropertyChanged和INotifyDataErrorInfo并提
关闭。这个问题需要更多 focused .它目前不接受答案。 想改进这个问题?更新问题,使其仅关注一个问题 editing this post . 5年前关闭。 Improve this questi
我的应用程序中有 2 个 ViewModel。第一个(FirstPageViewModel)负责在我的 View 中的文本框中显示的数据。另一个 ViewModel (NavigationViewMo
这是我目前实现INotifyPropertyChanged的方式- public class ViewModel : INotifyPropertyChanged { public Perso
我的问题似乎是“范围”,尽管我不确定这是正确的术语。我想在设置自定义对象中的属性时通知只读列表重新评估自身。我相信它根本不知道它的存在。也许有一个简单的方法可以解决这个问题,我想不出,但我正在画一个空
在 WPF 中,我们(至少)有两个线程:渲染线程和 UI 线程。当我针对某些属性更改引发事件 OnNotifyPropertyChanged 时,它会在 UI 线程上引发。需要将此信息分派(dispa
下面的代码基于此 post : 我的问题:在这个简单的示例中,我看不出我做错了什么来让 INotifyPropertyChanged 导致 textBox1 绑定(bind)自动反射(reflect)
INotifyPropertyChanged 在 View 模型中对于数据绑定(bind)到 View 显然非常有用。当我想要通知属性更改时,我是否也应该在我的应用程序的其他部分(例如业务层)中使用此
假设我有一个订单行对象集合... public class OrderLine { public decimal Qty { get; set; } public decimal Co
我在此链接中看到以下代码:An elegant way to implement INotifyPropertyChanged 我是表达式树的新手。谁能解释一下这段代码是如何简单工作的? 谢谢 pri
我在给定 Type 的字段和属性上循环,我想测试字段类型或属性 Type 是否实现了 INotifyPropertyChanged。 也许这听起来很奇怪,但我会解析字段/属性,例如字符串、整数和其他类
我是一名优秀的程序员,十分优秀!