同步用户控件中多个属性的绑定 [英] Synchronize Bindings of multiple Properties in a UserControl

查看:100
本文介绍了同步用户控件中多个属性的绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有WPF用户控件的丑陋竞争条件,它是某种扩展的ComboBox:
UserControl主要定义了两个可绑定的DependencyProperties,一个是选中的项,另一个是列表,从中选择可以选择的项目。
两者都是可绑定的,因此可以在有或没有选定项的情况下初始化控件,并且可以通过绑定(在DataContext更改时)更改两个属性,并且由于用户交互,选择可能还会更改。
UserControl包含一个ComboBox,它的ItemsSource和SelectedItem与我的UserControl的list-property和SelectedItem同步-到目前为止非常好。
现在的麻烦是,如果在设置两个值都设置了新的DataContext时,从外部(同时)同时更改了两个属性,则偶尔会发生SelectedItem设置正确,但列表更新会导致选择被重置的情况。为空覆盖先前设置的值->破坏我的DataContext。

I have an ugly race condition with a WPF usercontrol, which is some kind of extended ComboBox: The UserControl mainly defines two bindable DependencyProperties, one is the selected item, another one is a list, from which the selected item can be chosen. Both are bindable, so the control may be initialized with or without a selected item and both properties can be changed via binding (on DataContext change), further the selection may change due to user interaction. The UserControl contains a ComboBox, whose ItemsSource and SelectedItem are synchronized with my list-property and SelectedItem of the UserControl - so far so good. The trouble now is, that if both properties are changed (quasi simultaneously) from outside when setting a new DataContext with both values set, it occasionally happens that the SelectedItem is set correctly but the list update causes the selection to be reset to null overwriting the previously set value -> corrupting my DataContext.

简而言之:我需要找到一种在列表更新期间锁定我的SelectedItem的方法-但是仅观察PropertyChanged-Events是不够的,因为在更新后我会收到它们,而要记住的状态已经丢失。此外,我无法确定选择更改是由用户引起的,还是由(正确)绑定引起的,或者是由其他绑定间接引起的(不期望的)...
我想我需要一些BeforePropertyChanged或OnPropertyChanging事件DependencyProperties-或管理这两个属性的同时更新顺序的另一种方法。

To make it short: I need to find a way to "lock" my SelectedItem during list update - but just observing the PropertyChanged-Events is not enough, since I receive them AFTER the updates, where the state to remember is already lost. Further I cannot identify, if the selection change was caused by the user or by (correctly) the binding or (not desired) indirectly by the other binding... I think I would need some BeforePropertyChanged or OnPropertyChanging event for my DependencyProperties - or another way to manage the ordering of simultanous updates of both properties.

欢迎任何建议:)

请注意,我说的是从列表中选择项目的列表,但是实际上它是一个更复杂的结构,可以快速进行排序和过滤,这也是为什么我在这里不使用ItemsControl的原因,但我不喜欢

Note that I talk of a list to select an item from, but actually it is some more complex structure that allows quick sorting and filtering, that is also the reason why I do not use an ItemsControl here, but I don't feel like that's relevant for the question.

推荐答案

这可能对情况没有帮助,但是可能不是正确的方法您谈到依赖项属性的 OnPropertyChanging 事件。

This may not help the situation, and is probably not the right way to do this, however you spoke of an OnPropertyChanging event for your dependency properties.

恰好发生在创建依赖项属性时,您可以在 PropertyMetadata 中指定一个回调,当属性更改,它的 EventArgument 中具有旧值和新值。

It just so happens that when you create dependency properties you can specify a callback in the PropertyMetadata that fires when the property changes, which has both the old and the new values in its EventArgument.

以下是带有回调的Text属性的示例

Here is an example of a Text property with a callback

public static DependencyProperty TextProperty = DependencyProperty.Register
                                                ("Text", typeof(string), 
                                                 typeof(DecimalTextBox), 
                                                 new PropertyMetadata("", OnTextPropertyChanged));

最后一个参数是您要查找的参数。 PropertyMetadata构造函数的第一个参数是该属性的默认值。第二个是您注册一个属性更改的回调,该回调在属性更改时发生。

The last parameter is the one you are looking for. The first parameter of the PropertyMetadata constructor is a default value for the property. The second one is where you register a propertychanged callback that happens when the property changes.

在此回调中,您可以处理绑定以确保您不会覆盖自己的数据上下文的SelectedItem。

in this callback you can handle the bindings to make sure that you don't overwrite your datacontext's SelectedItem.

private static void OnTextPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {

        var box = ((TextBox)sender);

        if (((string)e.NewValue)==badvalue)
                box.Text= e.OldValue);


    }

说实话我不确定这将如何帮助您解决您的情况,因为我仍然不知道如何检查null值是否有效。 (如果没有ItemsSource,除非可能更改ItemsSource,否则我可能会做的是不允许空值[而且我可能会在ItemsSource更改的回调中使用某种标志,一旦更改了selecteditem,该回调就会重置)。我对异步不是很了解,但是您也许可以在这里加一些锁定。

To be honest I'm not sure how this helps you with your situation, as I would still not know how to check whether the null value is valid or not. (what I might do is not allow null values if there is an ItemsSource unless the itemssource is just changing [and I might use some kind of flag in the ItemsSource changed callback that gets reset once the selecteditem is changed]). I'm not very clued up on async, but you could perhaps put some sort of lock in here.

u_u

这篇关于同步用户控件中多个属性的绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆