我有一个丑陋的竞争条件与WPF usercontrol,这是一种扩展的ComboBox: UserControl主要定义两个可绑定的DependencyProperties,一个是所选项,另一个是列表,可以从中选择所选项。 两者都是可绑定的,因此可以使用或不使用所选项来初始化控件,并且可以通过绑定(在DataContext更改上)更改这两个属性,进一步选择可能由于用户交互而改变。 UserControl包含一个ComboBox,其ItemsSource和SelectedItem与我的list-property和UserControl的SelectedItem同步 - 到目前为止一直很好。 现在的麻烦是,如果在设置两个值设置的新DataContext时从外部更改两个属性(准同时),有时会发生SelectedItem设置正确但列表更新导致选择重置为null覆盖先前设定值 - >破坏了我的DataContext。
简而言之:我需要找到一种在列表更新期间“锁定”我的SelectedItem的方法 - 但只是观察PropertyChanged-Events是不够的,因为我在更新后收到它们,其中要记住的状态已经是丢失。此外,我无法确定,如果选择更改是由用户引起的,还是(正确地)绑定或(不希望)由其他绑定间接引起的... 我想我的DependencyProperties需要一些BeforePropertyChanged或OnPropertyChanging事件 - 或者另一种方法来管理两个属性的同时更新的顺序。
欢迎任何建议:)
请注意,我谈到一个列表来选择一个项目,但实际上它是一个更复杂的结构,允许快速排序和过滤,这也是我不在这里使用ItemsControl的原因,但我不觉得这与这个问题有关。
答案 0 :(得分:1)
这可能对情况没有帮助,可能不是正确的方法,但是你谈到了依赖属性的OnPropertyChanging
事件。
恰好在创建依赖项属性时,您可以在PropertyMetadata
中指定一个回调,该回调在属性更改时触发,其EventArgument
中包含旧值和新值。
以下是带回调的Text属性的示例
public static DependencyProperty TextProperty = DependencyProperty.Register
("Text", typeof(string),
typeof(DecimalTextBox),
new PropertyMetadata("", OnTextPropertyChanged));
最后一个参数是您要查找的参数。 PropertyMetadata构造函数的第一个参数是属性的默认值。第二个是注册属性更改时发生的propertychanged回调。
在这个回调中你可以处理绑定,以确保你不会覆盖你的datacontext的SelectedItem。
private static void OnTextPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var box = ((TextBox)sender);
if (((string)e.NewValue)==badvalue)
box.Text= e.OldValue);
}
老实说,我不确定这对你的情况有何帮助,因为我仍然不知道如何检查空值是否有效。 (如果存在ItemsSource,我可能会做的是不允许空值,除非itemssource正在改变[并且我可能在ItemsSource更改的回调中使用某种标志,一旦选择的itemitem被更改就会重置])。我对异步并不是很了解,但你可能会在这里放一些锁。
u_u