【问题标题】:WPF getter called multiple times多次调用 WPF getter
【发布时间】:2016-01-04 11:44:19
【问题描述】:

我有一个简单的 wpf 窗口:

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
    <StackPanel>
        <TextBox AcceptsReturn="True" Text="{Binding A}" /><!-- TextBox1 -->
        <TextBox AcceptsReturn="True" Text="{Binding B}" /><!-- TextBox2 -->
        <TextBox AcceptsReturn="True" Text="{Binding C}" /><!-- TextBox3 -->
    </StackPanel>
</Window>

with viewmodel(IronPython,在CodeBehind中设置为窗口的DataContext):

class TestViewModel(ViewModel):
    a_count = 0
    b_count = 0
    c_count = 0
    callStack = ''

    @property
    def A(self):
        self.a_count += 1
        self.callStack += 'A getter call {}\n'.format(self.a_count)
        return self.callStack

    @property
    def B(self):        
        self.b_count += 1
        self.callStack += 'B getter call {}\n'.format(self.b_count)
        return self.callStack

    @property
    def C(self):
        self.c_count += 1
        self.callStack += 'C getter call {}\n'.format(self.c_count)
        return self.callStack

,其中 ViewModel 是 INotifyPropertyChanged 的 C# 实现。

现在当我打开这个窗口时,三个TextBoxes 有以下内容:

(TextBox1)
A getter call 1
B getter call 1
C getter call 1
A getter call 2

(TextBox2)    
A getter call 1
B getter call 1
C getter call 1
A getter call 2
A getter call 3
B getter call 2
C getter call 2
B getter call 3

(TextBox3)
A getter call 1
B getter call 1
C getter call 1
A getter call 2
A getter call 3
B getter call 2
C getter call 2
B getter call 3
A getter call 4
B getter call 4
C getter call 3
C getter call 4

这里有一件主要的事情困扰着我:为什么每个 getter 都应该被调用来获取单个绑定的内容?为什么每个绑定属性的 getter 被调用两次?这意味着,为什么每次访问属性都会调用每个 getter,然后再次调用所需属性的实际 getter?

更糟糕的是:如果您从 xaml 中删除第二个(甚至第三个)TextBox,剩余的 TextBoxes 中的文本不会改变,这意味着未显示的属性的 getter 会被调用!

谁能解释这里发生了什么以及如何防止这种行为?

【问题讨论】:

    标签: wpf xaml ironpython getter


    【解决方案1】:

    我可以想象,由于 dlr,getter 经常被调用。 WPF 通常也使用 getter 进行类型检测。如果编译时不知道类型,只能这样解析。

    【讨论】:

      【解决方案2】:

      Getter 不应该改变对象的状态。基于此假设,各种服务可以随意调用它们。考虑例如当窗口需要重绘时。

      【讨论】:

      • 我在 C# 中尝试了“相同的代码”,但一切正常。
      猜你喜欢
      • 1970-01-01
      • 2014-09-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-07
      相关资源
      最近更新 更多