ContentControl中的WPF DependencyProperty不绑定TwoWay

时间:2017-09-18 13:54:33

标签: c# wpf xaml

我有自定义ContentControl

public class FilteringColumnHeader : ContentControl
{
    public static readonly DependencyProperty TextFieldProperty =
        DependencyProperty.Register("TextField", typeof(string), typeof(FilteringColumnHeader), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

    public string TextField
    {
        get
        {
            return (string)GetValue(TextFieldProperty);
        }
        set { SetValue(TextFieldProperty, value); }
    }
}

使用此模板样式

<Style TargetType="{x:Type c:FilteringColumnHeader}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type c:FilteringColumnHeader}">
                <DockPanel>
                    <ContentPresenter DockPanel.Dock="Top" Content="{TemplateBinding Content}" />
                    <TextBox Text="{TemplateBinding TextField}"/>
                </DockPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

这就是我在XAML的DataGrid中使用它的方式

<DataGridTextColumn x:Name="NameColumn" Header="Name" Binding="{Binding Name}" Width="*" MinWidth="50">
    <DataGridTextColumn.HeaderTemplate>
        <DataTemplate>
            <c:FilteringColumnHeader Content="{Binding }" Width="{Binding ActualWidth, ElementName=NameColumn}" TextField="{Binding DataContext.NameFilter, RelativeSource={RelativeSource AncestorType={x:Type local:GeneratorsListView}}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
        </DataTemplate>
    </DataGridTextColumn.HeaderTemplate>
</DataGridTextColumn>

和GeneratorsListView

private string nameFilter = "rec";
public string NameFilter
{
    get { return nameFilter; }
    set
    {
        nameFilter = value;
    }
}

我的问题是,Text绑定仅适用于OneWay。当我运行代码时,TextBox将填充“rec”,当我更改NameFilter时,TextBox也会更改。但是当我在那个框中输入内容时,没有任何反应(根本没有调用NameFilter的setter)。正如你所看到的,我试图将模式设置为TwoWay无处不在的地方。当我在TextBox内部定期DataTemplate并设置完全相同的文本绑定时,它正在工作。

1 个答案:

答案 0 :(得分:2)

{TemplateBinding}是模式为OneWay的绑定的优化版本,因此如果您希望更新属性,则应使用RelativeSource设置为{TemplatedParent的普通绑定1}}:

<ControlTemplate TargetType="{x:Type c:FilteringColumnHeader}">
    <DockPanel>
        <ContentPresenter DockPanel.Dock="Top" Content="{TemplateBinding Content}" />
        <TextBox Text="{Binding TextField, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource TemplatedParent}}"/>
    </DockPanel>
</ControlTemplate>