如何绑定到模板

How to bind through to a template

我正在尝试将 TextBox(和 ComboBox 当我开始工作时)添加到默认的 DataGridColumnHeader 并且已经像下面那样做了。这是在应用程序中 ResourceDirectory^:

<Style x:Key="DataGridColumnHeaderStyle_TextBox" TargetType="{x:Type DataGridColumnHeader}">
   <Setter Property="VerticalContentAlignment" Value="Center"/>
   <Setter Property="Template">
      <Setter.Value>
         <ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
            <Themes:DataGridHeaderBorder Grid.Row="0" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" IsClickable="{TemplateBinding CanUserSort}" IsPressed="{TemplateBinding IsPressed}" IsHovered="{TemplateBinding IsMouseOver}" Padding="{TemplateBinding Padding}" SortDirection="{TemplateBinding SortDirection}" SeparatorBrush="{TemplateBinding SeparatorBrush}" SeparatorVisibility="{TemplateBinding SeparatorVisibility}">
               <Grid>
                  <Grid.RowDefinitions>
                     <RowDefinition Height="*"/>
                     <RowDefinition Height="*"/>
                  </Grid.RowDefinitions>
                  <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                  <TextBox Grid.Row="1" Text="" HorizontalAlignment="Stretch" BorderThickness="1" />
                  <Thumb x:Name="PART_LeftHeaderGripper" HorizontalAlignment="Left" Style="{StaticResource ColumnHeaderGripperStyle}"/>
                  <Thumb x:Name="PART_RightHeaderGripper" HorizontalAlignment="Right" Style="{StaticResource ColumnHeaderGripperStyle}"/>
               </Grid>
            </Themes:DataGridHeaderBorder>
         </ControlTemplate>
      </Setter.Value>
   </Setter>
</Style>

在我的 Window DataGrid 我有以下内容:

<DataGridTextColumn Header="PO Number" Binding="{Binding PO_Number}" HeaderStyle="{DynamicResource DataGridColumnHeaderStyle_TextBox}"/>

这看起来是我现在想要的方式,Header 文本绑定到 ContentPresenter

问题

我该如何设置才能像这样绑定到新添加的 TextBox(或与此相关的任何对象):HeaderTemplate.TextBox.Text="{Binding SomeSubTotalClass}"

<DataGridTextColumn Header="PO Number" HeaderTemplate.TextBox.Text="{Binding SomeSubTotalClass}" Binding="{Binding PO_Number}" HeaderStyle="{DynamicResource DataGridColumnHeaderStyle_TextBox}"/>

您可以为自定义列创建一组附加属性 header。

public static class DataGridHeaderProperties
{
   public static readonly DependencyProperty TextProperty = DependencyProperty.RegisterAttached(
      "Text", typeof(string), typeof(DataGridHeaderProperties));

   public static string GetText(DependencyObject dependencyObject)
   {
      return (string)dependencyObject.GetValue(TextProperty);
   }

   public static void SetText(DependencyObject dependencyObject, string value)
   {
      dependencyObject.SetValue(TextProperty, value);
   }
}

然后调整您的列 header 模板,以便 TextBoxText 属性 绑定到相应的指定的附加 属性数据网格列定义。

<TextBox Grid.Row="1" Text="{Binding Column.(local:DataGridHeaderProperties.Text), RelativeSource={RelativeSource AncestorType={x:Type DataGridColumnHeader}}}" HorizontalAlignment="Stretch" BorderThickness="1" />

现在,在您的列定义中设置 属性。下面,只有一个用于测试的静态文本,但是您可以按照自己喜欢的方式绑定 属性。

<DataGridTextColumn Header="PO Number"
                    Binding="{Binding PO_Number}"
                    HeaderStyle="{StaticResource DataGridColumnHeaderStyle_TextBox}"
                    local:DataGridHeaderProperties.Text="My custom text"/>

但是请注意,列不是可视化树的一部分,也没有要绑定的数据上下文,因此您必须使用 binding proxy 或其他机制。这是DataGrid的一个众所周知的问题,不是这个问题的核心,但是Whosebug上已经有解决方案了。

您可以将此解决方案扩展到 header 列中的任何其他控件,例如 ComboBox。您只需要添加额外的附加属性,例如对于 ItemsSourceSelectedItem 等,但您还应该投入一些来提炼概念。将这些类型的控件放在 header 列中似乎很奇怪。它可能会损害您的应用程序的可用性。也许有更适合您要求的方法。