You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WinForms中BindingSource触发PropertyChanged后UltraCombo值重置问题

问题:UltraCombo绑定后修改其他属性触发ValueChanged导致值重置

场景重现

我将部分控件绑定至Windows.Forms.BindingSource,数据类实现INotifyPropertyChanged接口用于数据库交互,核心代码如下:

public class MyClass: INotifyPropertyChanged {

public String Bezeichnung 
{
    get => _row["bez"].ToString();
    set
    {
        if (value == null)
           _row["bez"] = DBNull.Value;
        else
           _row["bez"] = value;
        NotifyPropertyChanged();
     }
}

public event PropertyChangedEventHandler PropertyChanged;

protected void NotifyPropertyChanged([CallerMemberName] String name = "")
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
// 其他属性省略...

窗体中,第三方组合框Infragistics UltraCombo绑定至Bezeichnung属性,并设置了ValueChanged事件。但在事件中修改数据类的Otherproperty属性时,会再次触发该事件,组合框值被重置为初始值,无法正常修改:

private void Combo_ValueChanged(object sender, EventArgs e) 
{
   // 其他业务逻辑...
   dbclass.Otherproperty = 42.9; 
   // 修改该属性触发PropertyChangedEvent后,此函数再次被调用,组合框值恢复为初始值
}

我猜测这与PropertyChanged事件触发有关,BindingSource似乎会重新绑定所有数据。设置DataSourceUpdateMode.OnPropertyChanged也无效。


解决方案

核心原因

修改Otherproperty触发PropertyChanged时,若BindingSource的数据源是DataRowView这类数据库行对象,可能触发整个数据源刷新,导致BindingSource推送所有属性的变更通知——包括已修改的Bezeichnung。而你的Bezeichnung getter直接从_row["bez"]取值,若此时数据库行的bez字段未正确更新(或因某种原因回退旧值),就会导致UltraCombo接收到旧值通知,重置显示内容。此外,Infragistics UltraCombo的ValueChanged事件在数据绑定同步时也可能被触发,形成循环。

修复步骤

  1. 用本地字段缓存属性值,避免直接读写DataRow
    修改MyClass的Bezeichnung属性,用本地字段存储值,确保getter返回最新的修改后的值,不会因DataRow刷新回退:

    private string _bezeichnung;
    public string Bezeichnung 
    {
        get => _bezeichnung;
        set
        {
            if (_bezeichnung == value) return; // 避免无意义的变更通知
            _bezeichnung = value;
            _row["bez"] = value ?? DBNull.Value;
            NotifyPropertyChanged();
         }
    }
    
  2. 临时禁用事件避免循环触发
    在ValueChanged事件中修改Otherproperty前,先移除事件绑定,修改完成后重新绑定:

    private void Combo_ValueChanged(object sender, EventArgs e) 
    {
        // 临时移除事件绑定
        var combo = sender as UltraCombo;
        combo.ValueChanged -= Combo_ValueChanged;
        
        // 执行属性修改逻辑
        dbclass.Otherproperty = 42.9; 
        
        // 重新绑定事件
        combo.ValueChanged += Combo_ValueChanged;
    }
    
  3. 尝试替换为UltraCombo专属事件
    Infragistics控件提供了绑定相关的替代事件,比如SelectionChanged,可避免绑定同步时的误触发:

    private void Combo_SelectionChanged(object sender, EventArgs e) 
    {
        dbclass.Otherproperty = 42.9; 
    }
    
  4. 确认BindingSource配置
    确保BindingSource的DataSourceUpdateMode设置为OnPropertyChanged,同时数据类的PropertyChanged事件仅触发对应属性的通知(你的NotifyPropertyChanged使用CallerMemberName是正确的,无需修改)。

内容的提问来源于stack exchange,提问作者Me3nTaL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 10:07:11