控制不立即使用INotifyPropertyChanged更新绑定属性

Jos*_*ton 18 c# data-binding inotifypropertychanged winforms

我有控件在焦点丢失之前不更新绑定对象的相应属性.有类似的问题与引用的答案引用DataSourceUpdateMode.OnPropertyChange被声明,我这样做,但行为仍然存在.这是一个示例实现.我会尽量彻底,但要简洁.该MyConfig班是通过在Singleton类我称之为属性进行访问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);
    }
}
Run Code Online (Sandbox Code Playgroud)

鉴于以下简要实施,我不确定我可以忽视什么以确保立即改变房产.我可以在这种情况下发生变化,从FooBar在ComboBox,但除非我从ComboBox移除焦点,没有什么变化.有没有人有任何想法?

Nic*_*cki 24

WinForms ComboBox对于这个问题很不满意OnPropertyChanged.这是一个来自旧项目的代码,我曾经OnPropertyChanged按照我对该SelectedItem属性的预期方式工作.这适用于我的特定实例,但我通常很难让这种情况有时起作用.祝好运!

/// <summary>
/// A modification of the standard <see cref="ComboBox"/> in which a data binding
/// on the SelectedItem property with the update mode set to DataSourceUpdateMode.OnPropertyChanged
/// actually updates when a selection is made in the combobox.
/// </summary>
public class BindableComboBox : ComboBox
{
    /// <summary>
    /// Raises the <see cref="E:System.Windows.Forms.ComboBox.SelectionChangeCommitted"/> event.
    /// </summary>
    /// <param name="e">An <see cref="T:System.EventArgs"/> that contains the event data.</param>
    protected override void OnSelectionChangeCommitted(EventArgs e)
    {
        base.OnSelectionChangeCommitted(e);

        var bindings = this.DataBindings
            .Cast<Binding>()
            .Where(x => 
                x.PropertyName == "SelectedItem" && 
                x.DataSourceUpdateMode == DataSourceUpdateMode.OnPropertyChanged);
        foreach (var binding in bindings)
        {
            // Force the binding to update from the new SelectedItem
            binding.WriteValue();

            // Force the Textbox to update from the binding
            binding.ReadValue();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)