2015-10-07 51 views
1

我有簡單的WPF窗口: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> 

與視圖模型(IronPython的,被設定爲在代碼隱藏窗口的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 

,其中視圖模型是一個C# - 實現INotifyPropertyChanged

現在,當我打開這個窗口,三個TextBox ES有以下內容:

(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被調用兩次?這意味着,爲什麼每個獲取器都會被調用以獲取每個屬性,然後再次調用通用屬性的實際獲取器?

更糟糕的是:如果您從xaml中刪除第二個(甚至第三個)TextBox,則其餘TextBox es中的文本不會更改,這意味着未顯示屬性的getter會被調用!

任何人都可以解釋這裏發生了什麼,以及如何防止這種行爲?

回答

0

吸氣者應該不會改變物體的狀態。基於這些假設,各種服務隨時給他們打電話。考慮例如當窗口需要重新繪製時。

+1

我嘗試了C#中的'相同的代碼',但那裏一切都按預期工作。 –

0

我可以想象,吸氣人員經常因爲dlr而被調用。 WPF通常也使用getter來進行類型檢測。如果類型在編譯時不知道,只能像這樣解決。