控制不立即使用 INotifyPropertyChanged 更新绑定属性
我的控件在焦点丢失之前不会更新其绑定对象的各自属性。有类似的问题,接受的答案引用正在声明的 DataSourceUpdateMode.OnPropertyChange
,我这样做了,但行为仍然存在。这是一个示例实现。我会尽力做到彻底但简洁。 MyConfig
类是通过我称为 Configuration
的 Singleton 类中的属性来访问的。
[Serializable]
public class MyConfig : INotifyPropertyChanged
{
public enum MyEnum
{
Foo,
Bar
}
public MyConfig()
{
MyProperty = MyEnum.Foo;
}
private MyEnum _MyProperty;
public MyEnum MyProperty
{
get { return _MyProperty; }
set { if (value != _MyProperty) { _MyProperty = value; OnPropertyChanged("MyProperty"); } }
}
[field: NonSerialized]
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (string.IsNullOrEmpty(propertyName))
throw new ArgumentNullException(propertyName);
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public partial class ConfigForm : Form
{
public ConfigForm()
{
InitializeComponent();
MyComboBox.Items.AddRange(Enum.GetNames(typeof(MyConfig.MyEnum)));
}
private void ConfigForm_Load(object sender, EventArgs e)
{
MyComboBox.DataSource = Enum.GetValues(typeof(MyConfig.MyEnum));
MyComboBox.DataBindings.Add("SelectedItem", Configuration.Instance.MyConfig, "MyProperty", false, DataSourceUpdateMode.OnPropertyChanged);
}
}
鉴于以下简短的实现,我不确定我可以忽略什么以确保立即进行属性更改。在本例中,我可以将组合框中的 Foo
更改为 Bar
,但除非我从组合框中删除焦点,否则不会发生任何变化。有人有什么想法吗?
I have controls which are not updating their bound object's respective properties until focus is lost. There are similar questions with accepted answers referencing DataSourceUpdateMode.OnPropertyChange
being declared, which I do, yet the behavior persists. Here's an example implementation. I'll try to be thorough, yet concise. The MyConfig
class is accessed through a property in a Singleton class I call Configuration
.
[Serializable]
public class MyConfig : INotifyPropertyChanged
{
public enum MyEnum
{
Foo,
Bar
}
public MyConfig()
{
MyProperty = MyEnum.Foo;
}
private MyEnum _MyProperty;
public MyEnum MyProperty
{
get { return _MyProperty; }
set { if (value != _MyProperty) { _MyProperty = value; OnPropertyChanged("MyProperty"); } }
}
[field: NonSerialized]
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (string.IsNullOrEmpty(propertyName))
throw new ArgumentNullException(propertyName);
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public partial class ConfigForm : Form
{
public ConfigForm()
{
InitializeComponent();
MyComboBox.Items.AddRange(Enum.GetNames(typeof(MyConfig.MyEnum)));
}
private void ConfigForm_Load(object sender, EventArgs e)
{
MyComboBox.DataSource = Enum.GetValues(typeof(MyConfig.MyEnum));
MyComboBox.DataBindings.Add("SelectedItem", Configuration.Instance.MyConfig, "MyProperty", false, DataSourceUpdateMode.OnPropertyChanged);
}
}
I'm not sure, given the following brief implementation, what I could be overlooking to ensure immediate property changes. I can change, in this case from Foo
to Bar
in the ComboBox, but unless I remove focus from the ComboBox, nothing changes. Does anyone have any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
WinForms
ComboBox
对于OnPropertyChanged
来说是不稳定的。下面是一个旧项目中的一些代码,我用它来使OnPropertyChanged
按照我期望的SelectedItem
属性的方式工作。这适用于我的特定实例,但有时我通常很难让这种情况发挥作用。祝你好运!The WinForms
ComboBox
is wonky with regards toOnPropertyChanged
. Here's some code from an old project that I used to getOnPropertyChanged
working the way I expect for theSelectedItem
property. This works for my specific instance, but I usually struggle to get this scenario working sometimes. Good luck!@Nicholas Piasecki 值得赞扬,因为他引导我找到了解决方案,因此,除非您无法根据他的答案得出解决方案,否则请投票支持他的答案。
为了使此修复程序在我的情况下发挥作用,我必须进行三个主要更改。
我试图访问绑定到 ComboBox 的 SelectedValue 属性的对象上的属性。因此,我必须在 Linq where 子句中包含“SelectedValue”属性名称。
如果您通过 Visual Studio 中的表单设计器设置数据绑定,
并简单地设置 SelectedValue 或 SelectedItem 绑定的内容,默认值
数据源更新模式为“OnValidation”。如果您访问
ComboBox 上数据绑定的“(高级)”设置。
因此,如果您正在使用该数据源更新模式,则还必须包含该模式。
就我而言,我还必须在循环绑定并执行 Write/ReadValue 调用之后引发 OnSelectionChangeComfilled 事件。由于我订阅了表单上 ComboBox 的 SelectionChangeCommited 事件,因此在循环绑定并强制更新它们之前调用 base.OnSelectionChangeCommited 会导致绑定对象的属性仍未设置。
所以,这是我的 @Nicholas Piasecki 答案版本(也转换为 VB.NET):
@Nicholas Piasecki deserves credit for leading me to my solution so, unless you couldn't arrive at a solution based on his answer, please vote for his answer.
There were three main changes that I had to make for this fix to work in my situation.
I was trying to access the property on the object bound to the SelectedValue property of the ComboBox. Therefore, I had to include the "SelectedValue" property name in the Linq where clause.
If you're setting the databinding via the form designer in Visual Studio,
and simply set what the SelectedValue or SelectedItem is bound to, the default
datasource update mode is "OnValidation". You can see this if you go to the
"(Advanced)" settings for the databinding on the ComboBox.
So, you have to include that datasource update mode as well if that's what you're using.
In my case I also had to raise the OnSelectionChangeCommitted event after looping through the bindings and doing the Write/ReadValue calls. Since I was subscribing to SelectionChangeCommitted event of the ComboBox on the form, calling base.OnSelectionChangeCommitted before looping through the bindings and forcing them to update caused the bound object's property to still not be set.
So, here's my version of @Nicholas Piasecki's answer (also converted to VB.NET):