依赖属性可重入性(或:为什么这个有效?)

6
简单来说,在WPF控件中,我可以创建2个依赖属性,并在每个属性更改通知中放置代码以更改另一个属性(即PropA更改设置PropBPropB更改设置PropA)。
我希望这种情况不会出现,但是WPF似乎可以很好地处理它。对于我的目的来说,这实际上非常方便,但我无法在任何地方找到关于此行为的文档。
那么发生了什么?WPF依赖属性更改通知系统是否防止重入?
以下是代表性代码: XAML:
<Window x:Class="WPFReentrancy1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <TextBox Text="{Binding PropB, UpdateSourceTrigger=PropertyChanged}"/>

    </Grid>
</Window>

代码后台:

 public partial class MainWindow : Window
    {

        public string PropA
        {
            get { return (string)GetValue(PropAProperty); }
            set { SetValue(PropAProperty, value); }
        }
        public static readonly DependencyProperty PropAProperty =
                        DependencyProperty.Register("PropA", typeof (string), typeof (MainWindow),new UIPropertyMetadata("0", PropAChanged));


        public string PropB
        {
            get { return (string)GetValue(PropBProperty); }
            set { SetValue(PropBProperty, value); }
        }

        public static readonly DependencyProperty PropBProperty =
            DependencyProperty.Register("PropB", typeof (string), typeof (MainWindow), new UIPropertyMetadata("", PropBChanged));

        private static void PropBChanged(DependencyObject lDependencyObject, DependencyPropertyChangedEventArgs lDependencyPropertyChangedEventArgs)
        {
            ((MainWindow) lDependencyObject).PropA = (string) lDependencyPropertyChangedEventArgs.NewValue;
        }


        private static void PropAChanged(DependencyObject lDependencyObject, DependencyPropertyChangedEventArgs lDependencyPropertyChangedEventArgs)
        {
            ((MainWindow) lDependencyObject).PropB =
                double.Parse((string) lDependencyPropertyChangedEventArgs.NewValue).ToString("0.000");
        }


        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;
            PropA = "1.123";
        }
    }

没有确切的答案,但可以假设:考虑到 WPF 沿着元素树进行递归流以及相关属性,它只是“保存”(对于具体事件),它已经经过和触发通知的节点,因此如果再次遇到它们,就会跳过它们。 - Tigran
1个回答

4
那些回调函数只有在属性“改变”时才会触发,你的代码不会创建一个无限循环的“不同值”。尝试这样做,你会得到一个SO异常:
private static readonly Random _random = new Random();
private static void PropBChanged(DependencyObject lDependencyObject, DependencyPropertyChangedEventArgs lDependencyPropertyChangedEventArgs)
{
    ((MainWindow)lDependencyObject).PropA = _random.Next().ToString();
}
private static void PropAChanged(DependencyObject lDependencyObject, DependencyPropertyChangedEventArgs lDependencyPropertyChangedEventArgs)
{
    ((MainWindow)lDependencyObject).PropB = _random.Next().ToString();
}

我猜名字就是线索!我原以为通知会被触发,但我刚刚进行了快速测试,似乎确实是这样。 - MarcE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接