2014-04-09 39 views
1

我在Windows窗体中试验数据绑定,发现一个我无法解释的小故障。我在这里发布这个问题,希望社区中的某个人能够拿出一个合理的答案。Windows窗体上的数据绑定属性时发生故障

我试图想出的结合依赖于操作其它值只读值一个聪明的办法,并自动更新它时,相关值的变化。

我创建了一个表格3个文本框,我想要的前2的总和出现在第三文本框。

下面的代码应该工作,但没有,至少不正确:

public class Model : INotifyPropertyChanged 
{ 
    private int m_valueA; 
    private int m_valueB; 

    public int ValueA 
    { 
     get { return m_valueA; } 
     set { m_valueA = value; RaisePropertyChanged("ValueA"); } 
    } 

    public int ValueB 
    { 
     get { return m_valueB; } 
     set { m_valueB = value; RaisePropertyChanged("ValueB"); } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    private void RaisePropertyChanged(string propertyName) 
    { 
     var handler = PropertyChanged; 
     if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

public class DynamicBindingProperty<T> : INotifyPropertyChanged 
{ 
    private Func<T> m_function; 
    private HashSet<string> m_properties; 

    public DynamicBindingProperty(Func<T> function, INotifyPropertyChanged container, IEnumerable<string> properties) 
    { 
     m_function = function; 
     m_properties = new HashSet<string>(properties); 
     container.PropertyChanged += DynamicBindingProperty_PropertyChanged; 
    } 

    public T Property { get { return m_function(); } } 

    void DynamicBindingProperty_PropertyChanged(object sender, PropertyChangedEventArgs e) 
    { 
     if (!m_properties.Contains(e.PropertyName)) return; 
     if (PropertyChanged == null) return; 
     PropertyChanged(this, new PropertyChangedEventArgs("Property")); 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
} 

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
     InitializeDataBinding(); 
    } 

    private void InitializeDataBinding() 
    { 
     Model model = new Model(); 
     DynamicBindingProperty<int> tmp = new DynamicBindingProperty<int>(() => model.ValueA + model.ValueB, model, new[] {"ValueA", "ValueB"}); 

     textBox1.DataBindings.Add("Text", model, "ValueA"); 
     textBox2.DataBindings.Add("Text", model, "ValueB"); 
     textBox3.DataBindings.Add("Text", tmp, "Property"); 

     tmp.PropertyChanged += (sender, args) => Console.WriteLine(args.PropertyName); 
    } 
} 

经历过了一段时间后,我试图重新命名DynamicBindingProperty <牛逼> .Property到别的东西(如DynamicProperty)和一切都按预期工作!。现在,我期待通过将Model.ValueA重命名为Property来破解某些内容,但它没有,并且仍然无懈可击。

这是怎么回事?

回答

2

我做了一些调试,它看起来像一个bug(或要求“的属性不能被命名为房产”我不知道)。如果您有

PropertyChanged(this, new PropertyChangedEventArgs(null)); 

更换

PropertyChanged(this, new PropertyChangedEventArgs("Property")); 

它仍然无法正常工作 - null或空字符串是指任何财产可能已经改变。这表明问题不在于处理更改通知,而是绑定尚未正确建立。

如果添加第二个属性Property2DynamicBindingProperty<T>,做同样的Property并将其绑定到第四个文本框,然后文本框将得到正确更新,如果你有一个空字符串进行变更通知,null"Property2"。如果您有"Property"执行变更通知双方文本框将得到正确更新。这表明绑定到Property并未完全中断,并且更改通知有些中断。

可悲的是我无法牵制确切位置不如意的事情,但如果你投入足够的时间,通过优化框架源代码步进你或许可以找到答案。与属性名Property2与属性名Property的情况下与外壳之间的差别最早处理更改通知时,我能确定是OnValueChanged()内部类System.ComponentModel.ReflectPropertyDescriptor。在一种情况下,基础实现在另一种情况下被跳过时调用 - 至少如果调试器不欺骗我,但在优化代码中很难说明。

相关问题