DataGridColumnHeader 中的 UserControl 不拉伸

UserControl in DataGridColumnHeader does not stretch

我正在尝试为我的 DataGrid 创建自定义 header,以便能够以强大的方式进行过滤。一切都像我想要的那样工作,除了 UserControl 不随列拉伸这一事实。我已将 UserControl 的背景涂成红色,以便能够在图像中更清楚地看到它。

我一直在这里和其他地方寻找答案,但我发现的所有内容都表明我不应该在 UserControl 中显式设置宽度,并且我已经检查过了。

我试过在 header 中添加网格,然后将用户控件放在 header 中,但这没有帮助。

下面是我如何将 UserControl 添加到 header 之一:

                <DataGridTextColumn Binding="{Binding Path=Description}">
                    <DataGridTextColumn.Header>
                            <views:FilterControl Header="Description"  FilterChangedEvent="Filtering_Changed" PropertyPath="Description"  /> 
                    </DataGridTextColumn.Header>
                </DataGridTextColumn>

这是完整的 UserControl xaml:

 <UserControl x:Class="White.Db.ContentOrderDb.Views.FilterControl"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:White.Db.ContentOrderDb.Views"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="120"   HorizontalAlignment="Stretch">
<UserControl.Resources>
    <Style TargetType="FrameworkElement" x:Key="IsEnabledStyle">
        <Setter Property="IsEnabled" Value="False"/>
        <Setter Property="OpacityMask" Value="Black"/>
        <Style.Triggers>
            <DataTrigger Binding="{Binding Path=FilterActive}" Value="True" >
                <Setter Property="IsEnabled" Value="True"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</UserControl.Resources>
<Grid Background="White">
    <TextBox Style="{StaticResource IsEnabledStyle}" TextChanged="SearchPatternText_Changed" Height="23" Margin="3,50,3,0" TextWrapping="Wrap" Text="{Binding Path=SearchPattern,UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top">
        <TextBox.BorderBrush>
            <LinearGradientBrush EndPoint="0,20" MappingMode="Absolute" StartPoint="0,0">
                <GradientStop Color="#FFABADB3" Offset="0.05"/>
                <GradientStop Color="#FFE2E3EA" Offset="0.07"/>
                <GradientStop Color="#FFB4B4B4" Offset="1"/>
            </LinearGradientBrush>
        </TextBox.BorderBrush>
    </TextBox>
    <Label Content="{Binding Path=Header}" VerticalAlignment="Top" Height="30" Background="gray"  Foreground="White" BorderBrush="#FFB6B6B6" BorderThickness="1"/>
    <CheckBox Unchecked="FilterDeActivated" Checked="FilterActivated" IsChecked="{Binding Path=FilterActive}" Content="Active" HorizontalAlignment="Left" Margin="3,32,0,0" VerticalAlignment="Top" BorderBrush="#FFB4B4B4"/>
    <ComboBox  SelectionChanged="ComboBox_SelectionChanged" Style="{StaticResource IsEnabledStyle}" Text="{Binding Path=ComboBoxText}" IsReadOnly="True" IsEditable="True" ItemsSource="{Binding Path=ComboBoxItems}" Margin="3,75,3,0" VerticalAlignment="Top">
        <ComboBox.BorderBrush>
            <LinearGradientBrush EndPoint="0,20" MappingMode="Absolute" StartPoint="0,0">
                <GradientStop Color="#FFABADB3" Offset="0.05"/>
                <GradientStop Color="#FFE2E3EA" Offset="0.07"/>
                <GradientStop Color="#FFB4B4B4" Offset="1"/>
            </LinearGradientBrush>
        </ComboBox.BorderBrush>
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <CheckBox Content="{Binding Path=Content}" IsChecked="{Binding Path=IsChecked}" Checked="CheckBox_CheckedChanged" Unchecked="CheckBox_CheckedChanged" />
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>
</Grid>

有什么想法吗?我还没有看到人们将 UserControls 添加到 headers 的任何示例,这是错误的方法吗?我所看到的只是正在使用的模板和样式。我已经将所有用于过滤的逻辑添加到用户控件及其视图模型中,因为我想重用它,所以我看不到模板如何帮助我。

谢谢!

/埃里克

如果将控件的 HorizontalAlignment 属性 设置为 Stretch,则告诉该控件尝试占用尽可能多的可用水平 space .这里的问题是托管您的控件的容器(它是 DataGridColumnHeader control in this case) tries to keep it's content to the left and take up as little horizontal space as possible - this is because it's HorizontalContentAlignment property is by default set to Left. So in order to allow your control to stretch freely you need to also set that property to Stretch. The easiest way of doing that is to utilize the DataGridColumn.HeaderStyle 属性:

<DataGridTextColumn Binding="{Binding Path=Description}">
    <DataGridTextColumn.Header>
        <views:FilterControl Header="Description" FilterChangedEvent="Filtering_Changed" PropertyPath="Description"  /> 
    </DataGridTextColumn.Header>
    <DataGridTextColumn.HeaderStyle>
        <Style TargetType="DataGridColumnHeader">
            <Setter Property="HorizontalContentAlignment" Value="Stretch" />
        </Style>
    </DataGridTextColumn.HeaderStyle>
</DataGridTextColumn>

您可能还需要尝试 DataGridColumnHeader 的其他属性以获得所需的结果 - 我注意到默认情况下它的内容被填充,并且既不设置 Padding 也不设置 Margin 属性有帮助,但是将 Background 属性 设置为 Transparent(或任何其他与此相关的属性)可以摆脱神秘的填充。

1.可以通过应用样式更改所有列 header 的样式:

<Style x:Key="DataGridColumnHeaderStyle1" TargetType="{x:Type DataGridColumnHeader}">
    <Setter Property="VerticalContentAlignment" Value="Center"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
                <Grid>
                    <Themes:DataGridHeaderBorder 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}">
                        <ContentPresenter HorizontalAlignment="Stretch" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                    </Themes:DataGridHeaderBorder>
                    <Thumb x:Name="PART_LeftHeaderGripper" HorizontalAlignment="Left" Style="{StaticResource ColumnHeaderGripperStyle}"/>
                    <Thumb x:Name="PART_RightHeaderGripper" HorizontalAlignment="Right" Style="{StaticResource ColumnHeaderGripperStyle}"/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

对 "copied template" 的重要修改是:

 <ContentPresenter HorizontalAlignment="Stretch" ... >

2。然后使用样式:

<DataGrid HorizontalContentAlignment="Stretch" x:Name="datagrid1" 
          ColumnHeaderStyle="{DynamicResource DataGridColumnHeaderStyle1}">