【问题标题】:DataGrid row content vertical alignmentDataGrid 行内容垂直对齐
【发布时间】:2011-04-28 05:33:03
【问题描述】:

我有一个来自 WPF 4.0 RTM 的常规 DataGrid,我在其中放置来自数据库的数据。为了使DataGrid 的风格简洁明快,我使用高/高行,默认情况下DataGrid 将行内容对齐在顶部垂直位置,但我想设置中心垂直对齐方式。

我已经尝试过使用这个属性

VerticalAlignment="Center"

DataGrid 选项中,但这对我没有帮助。

这是一个 XAML 代码示例,描述了我的 DataGrid 没有中心垂直对齐:

<DataGrid x:Name="ContentDataGrid"
    Style="{StaticResource ContentDataGrid}"
    ItemsSource="{Binding}"
    RowEditEnding="ContentDataGrid_RowEditEnding">
<DataGrid.Columns>
    <DataGridTextColumn Header="UserID"
            Width="100"
            IsReadOnly="True"
            Binding="{Binding Path=userID}" />
    <DataGridTextColumn Header="UserName"
            Width="100"
            Binding="{Binding Path=userName}" />
    <DataGridTextColumn Header="UserAccessLevel"
            Width="100"
            Binding="{Binding Path=userAccessLevel}" />
    <DataGridTextColumn Header="UserPassword"
            Width="*"
            Binding="{Binding Path=userPassword}" />
</DataGrid.Columns>
</DataGrid>

执行此代码的结果:

如您所见,所有行内容都有顶部垂直对齐。

为了使每行内容居中垂直对齐,我必须添加什么?

【问题讨论】:

  • 另一种方法,使用 DataGridColumn 继承:blog.smoura.com/… - 允许在继承的列上简单地设置 VerticalAlignment 属性 - 需要从每个使用的列类型继承,所以这是一个很大的限制。也许有人会将其转化为行为?

标签: c# wpf xaml datagrid vertical-alignment


【解决方案1】:

属性值VerticalAlignment="Center" 将使DataGrid 在其父元素中居中。

你可能想要VerticalContentAlignment

【讨论】:

    【解决方案2】:

    此问题的完整解决方案在 MSDN:Vertical alignment of DataGrid row content

    简而言之,在样式文件集中:

    <!--body content datagrid cell vertical centering-->
    <Style x:Key="Body_Content_DataGrid_Centering"
            TargetType="{x:Type DataGridCell}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type DataGridCell}">
                    <Grid Background="{TemplateBinding Background}">
                        <ContentPresenter VerticalAlignment="Center" />
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

    在窗口文件中:

    <DataGrid x:Name="ContentDataGrid"
            Style="{StaticResource ContentDataGrid}"
            CellStyle="{StaticResource Body_Content_DataGrid_Centering}"
            ItemsSource="{Binding}"
            RowEditEnding="ContentDataGrid_RowEditEnding">
        <DataGrid.Columns>
            <DataGridTextColumn Header="UserID"
                    Width="100"
                    IsReadOnly="True"
                    Binding="{Binding Path=userID}" />
            <DataGridTextColumn Header="UserName"
                    Width="100"
                    Binding="{Binding Path=userName}" />
            <DataGridTextColumn Header="UserAccessLevel"
                    Width="100"
                    Binding="{Binding Path=userAccessLevel}" />
            <DataGridTextColumn Header="UserPassword"
                    Width="*"
                    Binding="{Binding Path=userPassword}" />
        </DataGrid.Columns>
    </DataGrid>
    

    这会给你一个想要的结果:

    【讨论】:

    • 我知道这是一个旧答案。但是对于简单的内容居中来说,这不是很多工作吗?
    • 不幸的是,我没有找到任何其他简单的解决方案,如果你有这样的,请分享你的知识。
    • 主要原因是DataGrid包含DataGridRow,DataGridRow又包含DataGridCell,DataGridCell又包含Controls。您希望这些控件位于垂直中心。这就是 Toucki 正在做的事情。
    • 请注意,还有 DataGridColumn.CellStyle 属性。如果想将居中单元格样式应用于 DataGrid 但希望拉伸 1 或 2 列(例如具有自定义背景颜色和居中 TextBlock 的 DataGridTemplateColumn) - 使用 VerticalAlignment Stetched 定义新的 CellStyle,并将其分配给这些列,这将很有用。跨度>
    • IMO 不是硬编码“中心”值,而是在模板VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 中绑定单元格的 VerticalContentAlignment 值可能是值得的,这样它会在稍后设置时开始尊重它,你可以这样做app.xaml 中的 set-once 默认样式,不要再担心了。
    【解决方案3】:

    要设置单独的文本对齐方式,您可以使用:

    <DataGridTextColumn.ElementStyle>
       <Style TargetType="TextBlock">
           <Setter Property="TextAlignment" Value="Center" />
       </Style>
    </DataGridTextColumn.ElementStyle>
    

    【讨论】:

    • 是的,它可以工作(使用 VerticalAlignment,因为 TextAlignment 用于水平文本定位),但是您必须为所有列设置元素样式(复选框列和组合框列需要具有不同的样式)。
    • 喜欢这种方式,因为如果启用了网格线,它不会破坏网格线。
    【解决方案4】:

    以下代码将垂直对齐 DataGridTextColumn 单元格的内容:

    <DataGridTextColumn.ElementStyle>
        <Style TargetType="TextBlock">
            <Setter Property="VerticalAlignment" Value="Center"></Setter>
        </Style>
    </DataGridTextColumn.ElementStyle>
    

    编辑:我回到了这个问题,发现下面的解决方案效果更好,它将 DataGridTextRows 中所有单元格的内容水平和垂直居中。

    <UserControl.Resources>    
        <ResourceDictionary>
            <Style TargetType="DataGridCell">
                <Setter Property="HorizontalAlignment" Value="Stretch"></Setter>
                <Setter Property="VerticalAlignment" Value="Stretch"></Setter>
                <Setter Property="VerticalContentAlignment" Value="Stretch"></Setter>
                <Setter Property="TextBlock.TextAlignment" Value="Center"></Setter>
                <Setter Property="TextBlock.VerticalAlignment" Value="Center"></Setter>
            </Style>    
        </ResourceDictionary>
    </UserControl.Resources>
    

    【讨论】:

    • 不起作用。尝试设置 DataGrid RowHeight=100 以使行高于默认高度。网格线看起来很奇怪。您的第一个解决方案 (DataGridTextColumn.ElementStyle) 对我来说效果更好。
    【解决方案5】:

    您也可以不覆盖 ControlTemplate:

        <Style TargetType="{x:Type DataGridCell}">
        <Setter Property="VerticalAlignment" Value="Center" />
        </Style>
    

    【讨论】:

    • 不知道为什么这个答案没有任何投票。它比更复杂的答案要简单得多,而且效果很好!
    • 此答案仅在您没有垂直网格线时才有效。否则,如果您设置 RowHeight 属性,网格线将出现间隙。
    【解决方案6】:

    基于 Jamier 的回答,以下代码在使用自动生成的列时为我解决了问题:

    Style VerticalCenterStyle = new Style();
    
    public MainWindow()
    {
      // This call is required by the designer.
      InitializeComponent();
    
      VerticalCenterStyle.Setters.Add(new Setter(VerticalAlignmentProperty, VerticalAlignment.Center));
    }
    
    private void DataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
    {   
      if (e.Column is DataGridTextColumn) {
        ((DataGridTextColumn)e.Column).ElementStyle = VerticalCenterStyle;
      }
    }
    

    【讨论】:

      【解决方案7】:

      这个适合我

       <DataGrid.CellStyle>
         <Style TargetType="DataGridCell">              
           <Setter Property="TextBlock.TextAlignment" Value="Center"/>
           <Setter Property="Template">
             <Setter.Value>
               <ControlTemplate TargetType="{x:Type DataGridCell}">
                 <Grid Background="{TemplateBinding Background}">
                   <ContentPresenter VerticalAlignment="Center"/>
                 </Grid>
               </ControlTemplate>
             </Setter.Value>
           </Setter>
         </Style>
      </DataGrid.CellStyle>
      

      【讨论】:

        【解决方案8】:

        这是我的简单解决方案,而且效果很好

        <DataGridTemplateColumn Header="Hello" Width="200">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="World!" TextAlignment="Center" VerticalAlignment="Center"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        

        我将宽度设置为 200,以便您注意到差异。

        【讨论】:

        • 很简单,确实有效。并且使用静态资源更容易设置样式。
        【解决方案9】:

        如果有人可能像我一样需要它..

        要只影响单个列,您可以使用“ElementStyle”属性:

        <DataGrid ItemsSource="{Binding}">
            <DataGrid.Resources>
                <Style x:Key="DataGridVerticalText" TargetType="TextBlock">
                    <Setter Property="VerticalAlignment" Value="Center" />
                </Style>
            </DataGrid.Resources>
            <DataGrid.Columns>
                <DataGridTextColumn Header="Header Title" Binding="{Binding}" ElementStyle="{StaticResource DataGridVerticalText}" />
            </DataGrid.Columns>
        </DataGrid>
        

        【讨论】:

          猜你喜欢
          • 2016-10-19
          • 2015-03-07
          • 2012-03-04
          • 2013-02-22
          • 1970-01-01
          • 2016-11-20
          • 1970-01-01
          • 2015-06-21
          相关资源
          最近更新 更多