DataGridColumn标题模板中的按钮 - 无法解释的间距

时间:2016-08-23 18:37:24

标签: c# wpf

我有一个数据网格,其DataGridTemplateColumn看起来像这样:

<DataGridTemplateColumn>
    <DataGridTemplateColumn.HeaderTemplate>
        <DataTemplate>
            <ItemsControl ItemsSource="{Binding DataContext.SomeStrings, Source={StaticResource proxy}}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Horizontal"></StackPanel>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Border Width="30" Margin="0">
                            <TextBlock Text="{Binding}" TextAlignment="Left">
                                <TextBlock.LayoutTransform>
                                    <RotateTransform Angle="270" CenterX="0.5" CenterY="0.5"/>
                                </TextBlock.LayoutTransform>
                            </TextBlock>
                        </Border>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </DataTemplate>
    </DataGridTemplateColumn.HeaderTemplate>
    <DataGridTemplateColumn.HeaderStyle>
        <Style TargetType="DataGridColumnHeader">
            <Setter Property="HorizontalContentAlignment" Value="Stretch" />
            <Setter Property="VerticalContentAlignment" Value="Stretch" />
            <Setter Property="Margin" Value="0" />
        </Style>
    </DataGridTemplateColumn.HeaderStyle>

    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <ItemsControl ItemsSource="{Binding}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Horizontal"></StackPanel>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Border Width="30">
                            <Button>
                                <TextBlock Text="{Binding}"/>
                            </Button>
                        </Border>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

这个想法是拥有一组动态的&#34;列&#34;在一个数据网格中,但是有一个单独的列,它本身就是一个StackPanel,并且通过在CellTemplate中使用相同的东西,我可以很好地排列所有内容。这个想法出现在这里:http://blogs.msmvps.com/deborahk/populating-a-datagrid-with-dynamic-columns-in-a-silverlight-application-using-mvvm/

它适用于我正在做的事情。但是,我想将TextBlock中的HeaderTemplate打包在Button中。所以像这样:

<DataGridTemplateColumn.HeaderTemplate>
    <DataTemplate>
        <ItemsControl ItemsSource="{Binding DataContext.SomeStrings, Source={StaticResource proxy}}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal"></StackPanel>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Border Width="30" Margin="0">
                        <Button>
                            <TextBlock Text="{Binding}" TextAlignment="Left">
                                <TextBlock.LayoutTransform>
                                    <RotateTransform Angle="270" CenterX="0.5" CenterY="0.5"/>
                                </TextBlock.LayoutTransform>
                            </TextBlock>
                        </Button>
                    </Border>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </DataTemplate>
</DataGridTemplateColumn.HeaderTemplate>

问题在于这会引入一些额外的间距,我不能为我的生活找出它的来源:

enter image description here

请注意,如果没有按钮,它会很好地排列,但是按钮会向右移动几个像素。它在哪里获得这个额外的间距?我怎么能不这样做呢?我可以在我的StackPanel上获得一个负的左边距,但这感觉就像一个可怕的黑客。

正如您所看到的,无论出于何种原因,CellTemplate都不会发生同样的问题。

完成示例

MainWindow.xaml:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication1"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525" DataContext="{Binding RelativeSource={RelativeSource self}}">
    <Window.Resources>
        <FrameworkElement x:Key="proxy" DataContext="{Binding}"/>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <ContentControl Visibility="Collapsed"
             Content="{StaticResource proxy}"/>
        <DataGrid ItemsSource="{Binding SomeData}" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTemplateColumn>
                    <DataGridTemplateColumn.HeaderTemplate>
                        <DataTemplate>
                            <ItemsControl ItemsSource="{Binding DataContext.SomeStrings, Source={StaticResource proxy}}">
                                <ItemsControl.ItemsPanel>
                                    <ItemsPanelTemplate>
                                        <StackPanel Orientation="Horizontal"></StackPanel>
                                    </ItemsPanelTemplate>
                                </ItemsControl.ItemsPanel>
                                <ItemsControl.ItemTemplate>
                                    <DataTemplate>
                                        <Border Width="30" Margin="0" Background="Pink">
                                            <TextBlock Text="{Binding}" TextAlignment="Left" VerticalAlignment="Center">
                                                <TextBlock.LayoutTransform>
                                                    <RotateTransform Angle="270" CenterX="0.5" CenterY="0.5"/>
                                                </TextBlock.LayoutTransform>
                                            </TextBlock>
                                        </Border>
                                    </DataTemplate>
                                </ItemsControl.ItemTemplate>
                            </ItemsControl>
                        </DataTemplate>
                    </DataGridTemplateColumn.HeaderTemplate>
                    <DataGridTemplateColumn.HeaderStyle>
                        <Style TargetType="DataGridColumnHeader">
                            <Setter Property="HorizontalContentAlignment" Value="Stretch" />
                            <Setter Property="VerticalContentAlignment" Value="Stretch" />
                            <Setter Property="Margin" Value="0" />
                        </Style>
                    </DataGridTemplateColumn.HeaderStyle>

                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ItemsControl ItemsSource="{Binding}">
                                <ItemsControl.ItemsPanel>
                                    <ItemsPanelTemplate>
                                        <StackPanel Orientation="Horizontal"></StackPanel>
                                    </ItemsPanelTemplate>
                                </ItemsControl.ItemsPanel>
                                <ItemsControl.ItemTemplate>
                                    <DataTemplate>
                                        <Border Width="30">
                                            <Button>
                                                <TextBlock Text="{Binding}"/>
                                            </Button>
                                        </Border>
                                    </DataTemplate>
                                </ItemsControl.ItemTemplate>
                            </ItemsControl>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
        <DataGrid ItemsSource="{Binding SomeData}" AutoGenerateColumns="False" Grid.Row="1">
            <DataGrid.Columns>
                <DataGridTemplateColumn>
                    <DataGridTemplateColumn.HeaderTemplate>
                        <DataTemplate>
                            <ItemsControl ItemsSource="{Binding DataContext.SomeStrings, Source={StaticResource proxy}}">
                                <ItemsControl.ItemsPanel>
                                    <ItemsPanelTemplate>
                                        <StackPanel Orientation="Horizontal"></StackPanel>
                                    </ItemsPanelTemplate>
                                </ItemsControl.ItemsPanel>
                                <ItemsControl.ItemTemplate>
                                    <DataTemplate>
                                        <Border Width="30" Margin="0">
                                            <Button BorderThickness="0">
                                                <TextBlock Text="{Binding}" TextAlignment="Left">
                                                    <TextBlock.LayoutTransform>
                                                        <RotateTransform Angle="270" CenterX="0.5" CenterY="0.5"/>
                                                    </TextBlock.LayoutTransform>
                                                </TextBlock>
                                            </Button>
                                        </Border>
                                    </DataTemplate>
                                </ItemsControl.ItemTemplate>
                            </ItemsControl>
                        </DataTemplate>
                    </DataGridTemplateColumn.HeaderTemplate>
                    <DataGridTemplateColumn.HeaderStyle>
                        <Style TargetType="DataGridColumnHeader">
                            <Setter Property="HorizontalContentAlignment" Value="Stretch" />
                            <Setter Property="VerticalContentAlignment" Value="Stretch" />
                            <Setter Property="Margin" Value="0" />
                        </Style>
                    </DataGridTemplateColumn.HeaderStyle>

                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ItemsControl ItemsSource="{Binding}">
                                <ItemsControl.ItemsPanel>
                                    <ItemsPanelTemplate>
                                        <StackPanel Orientation="Horizontal"></StackPanel>
                                    </ItemsPanelTemplate>
                                </ItemsControl.ItemsPanel>
                                <ItemsControl.ItemTemplate>
                                    <DataTemplate>
                                        <Border Width="30">
                                            <Button>
                                                <TextBlock Text="{Binding}"/>
                                            </Button>
                                        </Border>
                                    </DataTemplate>
                                </ItemsControl.ItemTemplate>
                            </ItemsControl>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

MainWindow.xaml.cs:

public partial class MainWindow : Window
{
    public string[] SomeStrings { get; set; } = new[] { "Foo", "Bar" };

    public List<string[]> SomeData { get; set; } = new List<string[]>() { new[] { "a", "b" }, new[] { "c", "d" } };
    public MainWindow()
    {
        InitializeComponent();
    }
}

注意:我在没有按钮的情况下为示例添加了背景颜色,而我现在还不相信它们是完全意外接受的。我认为因为文本标签与顶部对齐(一旦旋转成为左侧),它们似乎排成一行,而当您添加按钮时,标签会转移到中心并且不会排成一行再

1 个答案:

答案 0 :(得分:1)

默认情况下,Button.HorizontalContentAligmentCenter,其中Textblocks.HorizontalAlignmentLeft。因此,当您将TextBlock包裹在Button中时,它会居中,但您的Textblock会在左侧展开..

您需要做的就是将顶部TextBoxes水平对齐设置为中心,您将看到相同的外观:

<Border Width="30" Margin="0" Background="Pink">
    <TextBlock Text="{Binding}" TextAlignment="Left" HorizontalAlignment="Center" VerticalAlignment="Center">
        <TextBlock.LayoutTransform>
            <RotateTransform Angle="270" CenterX="0.5" CenterY="0.5"/>
        </TextBlock.LayoutTransform>
    </TextBlock>
</Border>

enter image description here

如果你希望它们完全排成一行,那么摆脱Padding中的DataGridColumnHeader(NB将其设置为0会导致它被某些触发器覆盖?Haven没有得到现在是时候进行调查了。但如果你把它设置为以下内容:

<Style TargetType="DataGridColumnHeader">
    <Setter Property="HorizontalContentAlignment" Value="Center" />
    <Setter Property="VerticalContentAlignment" Value="Stretch" />
    <Setter Property="Margin" Value="0" />
    <Setter Property="Padding" Value="0,1" />
</Style>

你会得到你想要的间距:

enter image description here