0

我为 DataGrid 的 DataGridTextColumn 定义了以下 xaml 代码。

<DataGridTextColumn x:Name="UserIdColumn" Binding="{Binding Path=UserId}" HeaderStyle="{StaticResource DataGridHeaderStyle}"/>

这是 DataGridTextColumn 的 HeaderStyle

<Style x:Key="DataGridHeaderStyle" TargetType="{x:Type DataGridColumnHeader}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="DataGridColumnHeader">
                <StackPanel>
                    <TextBlock x:Name="ColumnName" Text="UserId" />
                    <TextBox x:Name="UserIdFilter" Width="100">
                        <i:Interaction.Triggers>
                            <i:EventTrigger EventName="TextChanged">
                                <cal:ActionMessage MethodName="UserIdFilterChanged">
                                    <cal:Parameter Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGridTextColumn}}, Path=Name}"/>
                                    <cal:Parameter Value="{Binding ElementName=UserIdFilter, Path=Text}" />
                                </cal:ActionMessage>
                            </i:EventTrigger>
                        </i:Interaction.Triggers>
                    </TextBox>
                </StackPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>    

正如人们所看到的,我正在尝试使用这行代码访问 DataGridColumnHeader 的 ControlTemplate 中的 DataGridTextColumn 的Name属性

<cal:Parameter Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGridTextColumn}}, Path=Name}"/>

上面的行返回null,为什么?

有没有其他方法可以从 DataGridColumnHeader 的控件模板中获取 DataGridTextColumn 的Name属性?

4

1 回答 1

2

您正在恢复空值有两个不同的原因:第一个是 DataGridTextColumn 不是可视化树的一部分,也不是数据网格的可视化实例。这只是描述应如何显示数据网格的列的一个实例。因此,DataGridTextColumn 不是您单元格祖先的一部分。我看到恢复 DataGridTextColumn 的唯一方法是以某种方式进行:

<TextBox x:Name="UserIdFilter" Width="100" Tag="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGrid}}, Path=Columns[0]}">

这样,您应该使用 DataGridTextColumn 的实例设置 Textbox 的 Tag 属性(您可以使用 snoop 检查它是否正常工作)

然后,解释为什么你有一个空值的第二个原因是 DataGridTextColumn 没有 Name 属性。您可以做的只是创建一个像这样的附加属性:

public class XamlHelper
{
    public static readonly DependencyProperty NameProperty = DependencyProperty.RegisterAttached("Name", typeof(string), typeof(XamlHelper));

    public static string GetName(DependencyObject obj)
    {
        return (string)obj.GetValue(NameProperty);
    }

    public static void SetName(DependencyObject obj, string value)
    {
        obj.SetValue(NameProperty, value);
    }
}

...用这个替换列定义的名称:

<DataGridTextColumn alias:XamlHelper.Name="UserIdColumn" Binding="{Binding Path=UserId}" HeaderStyle="{StaticResource DataGridHeaderStyle}"/>

并以这种方式检索属性:

<Style x:Key="DataGridHeaderStyle" TargetType="{x:Type DataGridColumnHeader}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="DataGridColumnHeader">
                <StackPanel>
                    <TextBlock x:Name="ColumnName" Text="UserId" />
                    <TextBox x:Name="UserIdFilter" Width="100"  Tag="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGrid}}, Path=Columns[0]}">
                        <i:Interaction.Triggers>
                            <i:EventTrigger EventName="TextChanged">
                                <cal:ActionMessage MethodName="UserIdFilterChanged">
                                    <cal:Parameter Value="{Binding ElementName=UserIdFilter, Path=Tag.(alias:XamlHelper.Name)}"/>
                                    <cal:Parameter Value="{Binding ElementName=UserIdFilter, Path=Text}" />
                                </cal:ActionMessage>
                            </i:EventTrigger>
                        </i:Interaction.Triggers>
                    </TextBox>
                </StackPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>   

...希望我没有在这段代码中犯太多错误,但我认为这样的事情应该可行

请注意,我使用的文本框的 tag 属性有一个缓冲区,因为我注意到绑定的 findAncestor 模式能够正确恢复数据网格(我在不是可视树的元素上遇到了一些问题)。也许在你的参数中有一个唯一的绑定也可以工作......

Tag 也很适合进行测试,因为它允许在 snoop 中查看值!

如果某些观点不够清楚,请不要犹豫

编辑: 我检查了 DataGridCOlumnHeaderClass 并且发现了似乎包含您期望的属性...因此,应该可以这样做:

<Style x:Key="DataGridHeaderStyle" TargetType="{x:Type DataGridColumnHeader}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="DataGridColumnHeader">
                <StackPanel>
                    <TextBlock x:Name="ColumnName" Text="UserId" />
                    <TextBox x:Name="UserIdFilter" Width="100"  Tag="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGridColumnHeader}}, Path=Column}">
                        <i:Interaction.Triggers>
                            <i:EventTrigger EventName="TextChanged">
                                <cal:ActionMessage MethodName="UserIdFilterChanged">
                                    <cal:Parameter Value="{Binding ElementName=UserIdFilter, Path=Tag.(alias:XamlHelper.Name)}"/>
                                    <cal:Parameter Value="{Binding ElementName=UserIdFilter, Path=Text}" />
                                </cal:ActionMessage>
                            </i:EventTrigger>
                        </i:Interaction.Triggers>
                    </TextBox>
                </StackPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>   
于 2012-11-14T10:01:43.643 回答