TextBlock文本不在DataGridCell中垂直居中

我在C#中创建一个DataGrid (来自代码隐藏/不是XAML),但无论我尝试什么,我都无法使文本在数据单元格中垂直居中:

]

我开始时:

 var CellStyle = new Style(typeof(DataGridCell)) { Setters = { new Setter(TextBlock.TextAlignmentProperty, TextAlignment.Center) } }; 

哪个正确地定位单元格并使文本水平居中(根据上面的屏幕截图)。

尝试垂直居中文本,我知道TextBlock不支持垂直内容对齐,只支持父元素中自己的垂直对齐。

根据这个问题( WPF TextBlock中的文本垂直对齐 )我试图使用Padding伪造它:

 var CellStyle = new Style(typeof(DataGridCell)) { Setters = { new Setter(TextBlock.PaddingProperty, new Thickness(5)), new Setter(TextBlock.TextAlignmentProperty, TextAlignment.Center) } }; 

这没有任何区别。 然后我尝试了这个:

 var CellStyle = new Style(typeof(DataGridCell)) { Setters = { new Setter(DataGridCell.VerticalContentAlignmentProperty, VerticalAlignment.Center), new Setter(TextBlock.TextAlignmentProperty, TextAlignment.Center), new Setter(TextBlock.VerticalAlignmentProperty, VerticalAlignment.Center) } }; 

结果导致:

添加new Setter(DataGridCell.HeightProperty, 50d),会生成屏幕截图#1。

如何在数据单元格中垂直居中显示文本?

使用Blend for Visual Studio,我们为DataGridCell提供了这种样式:

             

所以看起来没有任何默认支持来更改对齐。 通常, 应该具有以下代码:

  

然后我们可以改变DataGridCell样式中的VerticalContentAlignmentHorizontalContentAlignment来更改对齐。

这意味着如果使用XAML代码,只需附加上面的代码即可解决您的解决方案。 但是如果你想使用代码,它当然会更长,更复杂。

在这里,我向您介绍2个解决方案。 首先,为ControlTemplate构建VisualTree,并为DataGridCellTemplate属性设置该模板:

 //root visual of the ControlTemplate for DataGridCell is a Border var border = new FrameworkElementFactory(typeof(Border)); border.SetBinding(Border.BorderBrushProperty, new Binding("BorderBrush") { RelativeSource = RelativeSource.TemplatedParent }); border.SetBinding(Border.BackgroundProperty, new Binding("Background") {RelativeSource = RelativeSource.TemplatedParent }); border.SetBinding(Border.BorderThicknessProperty, new Binding("BorderThickness") {RelativeSource = RelativeSource.TemplatedParent }); border.SetValue(SnapsToDevicePixelsProperty, true); //the only child visual of the border is the ContentPresenter var contentPresenter = new FrameworkElementFactory(typeof(ContentPresenter)); contentPresenter.SetBinding(SnapsToDevicePixelsProperty, new Binding("SnapsToDevicePixelsProperty") {RelativeSource=RelativeSource.TemplatedParent }); contentPresenter.SetBinding(VerticalAlignmentProperty, new Binding("VerticalContentAlignment") { RelativeSource = RelativeSource.TemplatedParent }); contentPresenter.SetBinding(HorizontalAlignmentProperty, new Binding("HorizontalContentAlignment") {RelativeSource = RelativeSource.TemplatedParent }); //add the child visual to the root visual border.AppendChild(contentPresenter); //here is the instance of ControlTemplate for DataGridCell var template = new ControlTemplate(typeof(DataGridCell)); template.VisualTree = border; //define the style var style = new Style(typeof(DataGridCell)); style.Setters.Add(new Setter(TemplateProperty, template)); style.Setters.Add(new Setter(VerticalContentAlignmentProperty, VerticalAlignment.Center)); style.Setters.Add(new Setter(HorizontalContentAlignmentProperty, HorizontalAlignment.Center)); yourDataGrid.CellStyle = style; 

第二种解决方案是使用XamlReader直接解析XAML代码,这意味着我们需要在保存在字符串中之前给出的确切XAML代码, XamlReader将解析该字符串,给出Style的实例:

 var xaml = ""; var parserContext = new System.Windows.Markup.ParserContext(); parserContext.XmlnsDictionary .Add("","http://schemas.microsoft.com/winfx/2006/xaml/presentation"); parserContext.XmlnsDictionary .Add("x","http://schemas.microsoft.com/winfx/2006/xaml"); yourDataGrid.CellStyle = (Style)System.Windows.Markup.XamlReader.Parse(xaml,parserContext); 

您可以看到两种解决方案都相当长,但它们实际上是您应该使用后面的代码。 这意味着我们应该尽可能地使用XAML代码。 WPF中的许多function主要是为XAML代码设计的,因此使用后面的代码当然不是直截了当且通常很冗长。

注意 :我在开头发布的XAML代码不是DataGridCell的完整默认样式,它有一些Triggers 。 这意味着代码可能会更长,抱歉,这是完整的默认XAML代码:

  

但是我刚测试它,看起来默认样式总是应用于DataGridCell ,它只是被你添加的Setter覆盖(设置相同的属性)。 这是测试代码, Trigger仍然有效:

 //change the highlight selected brush to Red (default by blue). yourDataGrid.Resources.Add(SystemColors.HighlightBrushKey, Brushes.Red); 

我的回答只是总结了King King的,以防它帮助某人。 在XAML中:

DataGrid中使用属性CellStyle="{StaticResource CustomCell}"