C#&;wpf-ListBox标签组合框之间(单向模式)链绑定的意外行为
我(对我)有以下奇怪的情况C#&;wpf-ListBox标签组合框之间(单向模式)链绑定的意外行为,c#,wpf,data-binding,two-way-binding,C#,Wpf,Data Binding,Two Way Binding,我(对我)有以下奇怪的情况 ListBox以单向模式绑定(作为源)到标签,即ListBox是只读的。 然后将标签绑定到具有双向绑定的组合框 ListBox --> Label <--> ComboBox - arrows denote binding mode private void comboBox_DropDownClosed(object sender, System.EventArgs e) { Binding binding = BindingO
ListBox以单向模式绑定(作为源)到标签,即ListBox是只读的。 然后将标签绑定到具有双向绑定的组合框
ListBox --> Label <--> ComboBox - arrows denote binding mode
private void comboBox_DropDownClosed(object sender, System.EventArgs e)
{
Binding binding = BindingOperations.GetBinding(label, Label.ContentProperty);
if (binding != null)
{
ComboItems ComboItem = comboBox.SelectedItem as ComboItems;
int iDX = ComboItem.iDX;
// Set label value without affecting existing binding
label.SetCurrentValue(Label.ContentProperty, iDX);
}
}
在我看来,Combobox双向绑定仍然在使用SetValue,这就是为什么在使用my(Combobox)时,(label)的绑定会被删除的原因
为了克服这个问题,我将(comboBox)的双向绑定改为单向绑定,并在comboBox_DropDownClosed事件(显示当前选中的项)中输入以下内容,以便在不删除现有绑定的情况下通过代码更新(标签)
ListBox --> Label <--> ComboBox - arrows denote binding mode
private void comboBox_DropDownClosed(object sender, System.EventArgs e)
{
Binding binding = BindingOperations.GetBinding(label, Label.ContentProperty);
if (binding != null)
{
ComboItems ComboItem = comboBox.SelectedItem as ComboItems;
int iDX = ComboItem.iDX;
// Set label value without affecting existing binding
label.SetCurrentValue(Label.ContentProperty, iDX);
}
}
使用SetCurrentValue后,代码现在可以通过“模拟”双向模式正常工作。一点也不奇怪。数据绑定就是这样设计的。将绑定指定给依赖项属性时,意味着您将此依赖项属性的本地值更改为绑定表达式。绑定源提供的任何更新都将是此依赖项属性的有效值。如果绑定以单向模式工作,则从其他绑定源对此依赖项属性的任何更新都将覆盖本地值,从而导致绑定丢失。另一方面,由于假设使用两种模式来更新绑定源,依赖项对象会将任何非表达式值计算为有效值,绑定将继续工作,直到您替换或清除它为止
获取有效值DependencyObject.GetValue
获取本地值DependencyObject.ReadLocalValue
设置本地值DependencyObject.SetValue
设置有效值DependencyObject.SetCurrentValue
清除本地值DependencyObject.ClearValue
获取有效值DependencyObject.GetValue
获取本地值DependencyObject.ReadLocalValue
设置本地值DependencyObject.SetValue
设置有效值DependencyObject.SetCurrentValue
清除本地值DependencyObject.ClearValue
- 一点也不奇怪。数据绑定就是这样设计的。将绑定指定给依赖项属性时,意味着您将此依赖项属性的本地值更改为绑定表达式。绑定源提供的任何更新都将是此依赖项属性的有效值。如果绑定以单向模式工作,则从其他绑定源对此依赖项属性的任何更新都将覆盖本地值,从而导致绑定丢失。另一方面,由于假设使用两种模式来更新绑定源,依赖项对象会将任何非表达式值计算为有效值,绑定将继续工作,直到您替换或清除它为止
SelectedItem.iLDX
,不如绑定到SelectedValue
,并在列表框上设置SelectedValuePath=“iLDX”
,就像在组合框上一样。谢谢您的建议。这里显示的代码只是为了演示这个案例。我的real ListBox有15个以上的字段和其他类似的索引,因此SelectedValuePath不能应用于此。你是对的,我在注释掉的代码中有一个令人困惑的语句,现在已经更正了。“尽管如此,问题仍然存在。”克莱门斯有很好的建议。不要在控件之间进行绑定,只绑定到ViewModel。这样,它总是按照您的期望工作,即使您不了解绑定Framework的详细信息,我很抱歉,但我不使用任何ViewModel,也不打算使用。我为业余爱好和娱乐而编码,而且是用老式的方式。同时,我希望基本的语言功能能够正常工作,而不必经过北极去巴黎:)为了避免这样的混乱,将所有控件绑定到一个公共视图模型。请注意,与其将标签内容绑定到SelectedItem.iLDX
,不如绑定到SelectedValue
,并在列表框上设置SelectedValuePath=“iLDX”
,就像在组合框上一样。谢谢您的建议。这里显示的代码只是为了演示这个案例。我的real ListBox有15个以上的字段和其他类似的索引,因此SelectedValuePath不能应用于此。你是对的,我在注释掉的代码中有一个令人困惑的语句,现在已经更正了。“尽管如此,问题仍然存在。”克莱门斯有很好的建议。不要在控件之间进行绑定,只绑定到ViewModel。这样,它总是按照您的期望工作,即使您不了解绑定Framework的详细信息,我很抱歉,但我不使用任何ViewModel,也不打算使用。我为业余爱好和娱乐而编码,而且是用老式的方式。同时,我希望基本的语言功能能够正常工作,而不必经过北极去巴黎:)谢谢你的回答。请您提供一个链接,按照最初的要求记录这种行为,好吗?我这样问是因为,例如,当以单向模式绑定2个文本框,并且手动更新第二个文本框(目标,设置绑定)时,绑定将继续正常工作,即,第一个(源)文本框中输入的所有文本将通过绑定显示在第二个文本框中,即使第二个文本是独立手工修改的。但是当第二个Textbox.Text属性被代码更改时,绑定被清除,因此行为不一致。@john_m实际上,我知道没有任何官方文档。但是你可以从DependencyObj的源代码中找到这个事实
private void comboBox_DropDownClosed(object sender, System.EventArgs e)
{
Binding binding = BindingOperations.GetBinding(label, Label.ContentProperty);
if (binding != null)
{
ComboItems ComboItem = comboBox.SelectedItem as ComboItems;
int iDX = ComboItem.iDX;
// Set label value without affecting existing binding
label.SetCurrentValue(Label.ContentProperty, iDX);
}
}