2017-04-19 60 views
1

問題:UpdateSourceTrigger總是需要更新源的屬性嗎?我似乎記得很久以前Mode = TwoWay就夠了。但是現在,我必須UpdateSourceTrigger = PropertyChanged?也許我失去了它...WPF UpdateSourceTrigger是否總是需要通知收集模型的變化?

 <DataGridTemplateColumn Header="Hub" Width="SizeToHeader"> 
      <DataGridTemplateColumn.CellTemplate> 
       <DataTemplate> 
        <CheckBox x:Name="XHub" IsChecked="{Binding Hub, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> 
       </DataTemplate> 
      </DataGridTemplateColumn.CellTemplate> 
     </DataGridTemplateColumn> 

當我省略了結合模型的那部分永遠不會調用當的ObservableCollection變化的值。

+0

「Mode = TwoWay」和「UpdateSourceTrigger = PropertyChanged」都是必需的,因爲它們都是默認值。 – Clemens

回答

1

綁定的Mode和UpdateSourceTrigger屬性取決於您綁定到的依賴項屬性。根據MSDN

默認值是Default,它將返回目標依賴項屬性的默認UpdateSourceTrigger值。但是,大多數依賴屬性的默認值是PropertyChanged,而Text屬性的默認值是LostFocus。

確定依賴項屬性的默認UpdateSourceTrigger值的編程方法是使用GetMetadata獲取屬性的屬性元數據,然後檢查DefaultUpdateSourceTrigger屬性的值。

所以你的情況,你都結合器isChecked是在ToogleButton類定義如下:

public static readonly DependencyProperty IsCheckedProperty = 
    DependencyProperty.Register("IsChecked", typeof (bool?), typeof (ToggleButton), 
    (PropertyMetadata) new FrameworkPropertyMetadata(
     BooleanBoxes.FalseBox, 
     FrameworkPropertyMetadataOptions.BindsTwoWayByDefault | FrameworkPropertyMetadataOptions.Journal, 
     new PropertyChangedCallback(ToggleButton.OnIsCheckedChanged))); 

所以BindsTwoWayByDefault使得Mode=TwoWay冗餘,同時 quering元數據:

var def = ((FrameworkPropertyMetadata)CheckBox.IsCheckedProperty.GetMetadata(typeof(CheckBox))).DefaultUpdateSourceTrigger; 

結果在PropertyChanged,這使得UpdateSourceTrigger=PropertyChanged部分還reduntant。

編輯: 關於這一部分:

當我忽略的模型的結合是從來沒有所謂的那一部分當的ObservableCollection變化的值。

很好,我不能解釋你自己已經注意到的行爲(但它很容易重現)。我期待根據依賴項屬性默認UpdateSourceTrigger綁定更新viewmodel。但是我注意到ViewModel甚至在焦點丟失時都沒有更新,但是當你將焦點移到下一行或者按下回車鍵。所以Colin Eberhardt在他的blog中給出的解釋似乎是我能找到的最好的解釋。很明顯,這種行爲與DataGrid強烈相關,如果您在網格外部具有相同的複選框,那麼ViewModel將按預期進行更新,而不會將明確的UpdateSourceTrigger設置爲PropertyChanged。

當您綁定到DataTable時,您實際上綁定到DataTable的DataView類型的DefaultView。因此,表的每一行都將綁定到DataRowView。如果您查看DataRowView的文檔,您會發現它實現了IEditableObject接口,這是此處的重要因素。這個接口允許你對你的對象執行trasnactional改變,也就是說你可以在'transaction'中改變對象的屬性,然後在一個原子操作中提交。默認情況下,當你綁定到一個DataGrid時,這發生在用戶完成編輯一行時,通過移動焦點或按Enter鍵。

+0

感謝您的回覆,您能否幫我理解這一部分「當我省略綁定的那部分時,ObservableCollection中的值發生更改時,模型永遠不會被調用。」 –

+1

嗯,我認爲這在[blog](http://blog.scottlogic.com/2009/01/21/wpf-datagrid-committing-changes-cell-by-cell.html)中有所解釋。我會用那裏的解釋更新我的答案。 – 3615

+0

好了,現在回到我身邊,我記得過去想通過在單元格中敲入回車鍵來從代碼後面提交更改。爲了實現這一點,我必須監視所有文本輸入並觸發該單元格的編輯結束狀態,以便觸發INPC事件。 –

-1

是否UpdateSourceTrigger始終需要具有屬性更新源?

號的結合指定什麼觸發源屬性的更新而Mode屬性可以控制數據流的方向的UpdateSourceTrigger屬性。這是兩件不同的事情。

即使您沒有明確設置UpdateSourceTrigger屬性,您的Hub源屬性仍然會設置,但直到您退出DataGrid的單元格爲止。