WPF UpdateSourceTrigger是否总是需要通知模型集合中的更改?

时间:2017-04-19 23:57:30

标签: wpf notifications inotifypropertychanged

问题:UpdateSourceTrigger是否总是需要让属性更新源?我似乎记得很久以前Mode = TwoWay已经足够了。但是现在,我必须更新UpdateSourceTrigger = PropertyChanged?也许我失去了它......

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

当我省略绑定的那部分时,当ObservableCollection中的值发生变化时,永远不会调用模型。

2 个答案:

答案 0 :(得分:1)

绑定的Mode和UpdateSourceTrigger属性取决于要绑定的依赖项属性。根据{{​​3}}:

  

默认值为Default,它返回目标依赖项属性的默认UpdateSourceTrigger值。但是,大多数依赖项属性的默认值是PropertyChanged,而Text属性的默认值是LostFocus。

     

确定依赖项属性的默认UpdateSourceTrigger值的编程方法是使用GetMetadata获取属性的属性元数据,然后检查DefaultUpdateSourceTrigger属性的值。

因此,在您的情况下,您绑定到ToogleButton类中定义的IsChecked,如下所示:

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多余,而 查询元数据:

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

结果为PropertyChanged,这使UpdateSourceTrigger=PropertyChanged部分也变得多余。

编辑:关于这一部分:

  

当我省略绑定的那部分时,当ObservableCollection中的值发生变化时,永远不会调用模型。

真诚地,我无法解释你已经注意到的行为(但它很容易重现)。我期望绑定根据依赖属性默认值UpdateSourceTrigger更新viewmodel。但我注意到,即使焦点丢失,ViewModel也不会更新,但是当您将焦点移动到下一行或按回车键时。所以Colin Eberhardt在{{​​3}}给出的解释似乎是我能找到的最好的。显然,此行为与DataGrid密切相关,如果您在网格外部具有相同的复选框,则ViewModel将按预期更新,而不将显式UpdateSourceTrigger设置为PropertyChanged。

  

绑定到DataTable时,实际上是绑定到DataTable的DefaultView,它是DataView类型。因此,表的每一行都将绑定到DataRowView。如果你看一下DataRowView的文档,你会发现它实现了IEditableObject接口,这是这里的重要因素。此界面允许您对对象执行事务更改,即您可以在“事务”中更改对象的属性,然后在单个原子操作中提交所有属性。默认情况下,当您绑定到DataGrid时,这会在用户完成编辑行时发生,无论是通过移动焦点还是按Enter键。

答案 1 :(得分:-1)

  

UpdateSourceTrigger是否总是需要让属性更新源?

没有。绑定的UpdateSourceTrigger属性指定什么触发源属性的更新,而Mode属性允许您控制数据流的方向。这是两件不同的事情。

即使您没有明确设置UpdateSourceTrigger属性,您的Hub源属性确实仍将设置,但直到您离开DataGrid的单元格。