我有自定义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
并设置完全相同的文本绑定时,它正在工作。
答案 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>