TextBlock 文本在 DataGridCell 内未垂直居中

2024-01-06

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

我从以下开始:

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

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

尝试将文本垂直居中,我知道TextBlock不支持垂直内容对齐,仅支持其在父元素内的垂直对齐。

根据这个问题(WPF TextBlock 中的文本垂直对齐 https://stackoverflow.com/questions/1491649/text-vertical-alignment-in-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)
    }
};

结果是:

Adding new Setter(DataGridCell.HeightProperty, 50d),结果截图#1。

如何使数据单元格中的文本垂直居中?


使用 Blend for Visual Studio,我们为DataGridCell:

<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="1"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type DataGridCell}">
                <Border BorderBrush="{TemplateBinding BorderBrush}" 
                        BorderThickness="{TemplateBinding BorderThickness}" 
                        Background="{TemplateBinding Background}" 
                        SnapsToDevicePixels="True"                          
                >
                    <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
</Setter>

所以看起来这里没有任何默认支持更改对齐方式。通常情况下<ContentPresenter>应该有这样的代码:

<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                  VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
                  HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/>

然后我们可以改变VerticalContentAlignment and HorizontalContentAlignment的风格DataGridCell更改对齐方式。

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

这里我给大家介绍2个解决方案。首先构建 VisualTreeControlTemplate并设置该模板Template的财产DataGridCell:

//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 = "<Style TargetType=\"{x:Type DataGridCell}\"><Setter Property=\"VerticalContentAlignment\" Value=\"Center\"/>" +
           "<Setter Property=\"HorizontalContentAlignment\" Value=\"Center\"/>" +
           "<Setter Property=\"Template\">" +
           "<Setter.Value><ControlTemplate TargetType=\"DataGridCell\">" +
           "<Border BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" SnapsToDevicePixels=\"True\">" +
           "<ContentPresenter SnapsToDevicePixels=\"{TemplateBinding SnapsToDevicePixels}\" VerticalAlignment=\"{TemplateBinding VerticalContentAlignment}\" HorizontalAlignment=\"{TemplateBinding HorizontalContentAlignment}\"/>" +
           "</Border></ControlTemplate></Setter.Value></Setter></Style>";

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 中的许多功能主要是针对 XAML 代码设计的,因此使用隐藏代码当然并不简单,而且通常很冗长。

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

<Style TargetType="{x:Type DataGridCell}">
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="BorderBrush" Value="Transparent"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type DataGridCell}">
                <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True"                            
                >
                    <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsSelected" Value="True">
            <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
            <Setter Property="BorderBrush" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
        </Trigger>
        <Trigger Property="IsKeyboardFocusWithin" Value="True">
            <Setter Property="BorderBrush" Value="{DynamicResource {x:Static DataGrid.FocusBorderBrushKey}}"/>
        </Trigger>
        <MultiTrigger>
            <MultiTrigger.Conditions>
                <Condition Property="IsSelected" Value="true"/>
                <Condition Property="Selector.IsSelectionActive" Value="false"/>
            </MultiTrigger.Conditions>
            <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
            <Setter Property="BorderBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}}"/>
        </MultiTrigger>
        <Trigger Property="IsEnabled" Value="false">
            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
        </Trigger>
    </Style.Triggers>
</Style>

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

//change the highlight selected brush to Red (default by blue).
yourDataGrid.Resources.Add(SystemColors.HighlightBrushKey, Brushes.Red);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

TextBlock 文本在 DataGridCell 内未垂直居中 的相关文章

  • 使用sqlbulkcopy之前如何创建表

    我有一个 DBF 文件 我正在尝试导入该文件 然后将其写入 SQL 表 我遇到的问题是 如果我使用 SqlBulkCopy 它需要我提前创建表 但在我的场景中这是不可能的 因为 dbf 文件不断变化 到目前为止 这是我的代码 public
  • 显示 div 内的用户名列表

    我是 jQuery 新手 在我的项目中 我创建了一个类User其中代码如下所示 static ConcurrentDictionary
  • C++ 中的“int”默认是“signed long int”吗?

    Is int默认情况下signed long int in C 它是否依赖于平台和 或编译器 如果是这样 怎么办 EDIT 以下任何一项是否保证是重复的 signed short int signed int signed long int
  • C# - Visual Studio 中的 System.OutOfMemoryException

    我遇到问题 当我右键单击 Visual Studio 中的主窗体并转到 视图设计器 时 出现错误 它说 引发了 System OutOfMemoryException 类型的异常 堆栈跟踪 at System Reflection Asse
  • 是否有可能将 *.pdb 文件包含到发布版本中以查看错误行号?

    我做了一个项目 所有设置都是默认的 当我在调试模式 构建配置 调试 下运行它并遇到异常时 它转储到我的自定义日志记录机制 其中包含错误行号 但是当我运行发布构建时 记录相同的异常 没有行号 只有方法抛出和记录调用堆栈 是否有可能在发布配置
  • 使用默认行为将模型绑定到接口

    我正在尝试将控制器操作绑定到接口 但仍保持默认的绑定行为 public class CoolClass ISomeInterface public DoSomething get set ISomeInterface public clas
  • 多个线程访问一个变量

    我在正在读的一本教科书中发现了这个问题 下面也给出了解决方案 我无法理解最小值怎么可能是 2 为什么一个线程不能读取 0 而所有其他线程都执行并写入 1 而无论是1还是2 最后写入的线程仍然必须完成自己的循环 int n 0 int mai
  • 使用 catch all 字典属性将 json 序列化为对象

    我想使用 JSON net 反序列化为对象 但将未映射的属性放入字典属性中 是否可以 例如给定 json one 1 two 2 three 3 和 C 类 public class Mapped public int One get se
  • 主构造函数不再在 VS2015 中编译

    直到今天 我可以使用主构造函数 例如 public class Test string text private string mText text 为了能够做到这一点 在以前的 Visual Studio CTP 中 我必须将其添加到 c
  • C# 反序列化过程中创建指向父对象的指针

    我有这样的课程 Serializable public class child public Parent parent Serializable public class Parent public List
  • 何时分离或加入 boost 线程?

    我有一个方法 大约每 30 秒触发一次 我需要在一个线程中包含它 我有一个可以从类外调用的方法 像 call Threaded Method 这样的东西会创建一个线程 该线程本身会调用最终的线程方法 这些是 MyClass 的方法 void
  • 禁用实体框架的默认值生成(Code First)

    我数据库中有一个列不能为空 我想将其设置为默认值在数据库中 问题是实体框架似乎自己创建了一个默认值 例如 int gt 0 并且完全忽略了数据库中的默认值约束 有没有办法禁用实体框架的默认值 我发现您可以使用以下属性来装饰您的字段 Data
  • 如何在 ASP.NET Core 项目中使用 MStest 测试 Ok() 结果

    我正在使用 MStest 来测试我的控制器 我想测试这个动作 HttpGet Name GetGroups public async Task
  • Code::Blocks 中的调试似乎不起作用 - 缺少调试符号

    我正在尝试在 Code Blocks 中调试程序 我跟着本指南 http wiki codeblocks org index php title Debugging with Code Blocks and 这个短视频 http www y
  • WPF 和 ClickOnce

    MSDN 未将 WPF exe 列为 ClickOnce 支持的应用程序类型 ClickOnce 应用程序是任何 Windows Presentation Foundation xbap Windows 窗体 exe 控制台应用程序 exe
  • 文本框中“结束编辑”的事件

    我正在 winform c 中使用文本框 并使用文本在数据库中进行查询 但每次文本更改时 我都需要不断查阅文本框的文本 因此 对于这些 我使用 KeyUp 但这个活动太慢了 文本框编辑完成后是否会触发任何事件 我考虑完成2个条件 控制失去焦
  • 使用 WinAPI 连接禁用的显示设备

    我的问题是启用禁用的监视器ChangeDisplaySettingsEx 我想这不是火箭科学 但经过一番挖掘后 它看起来仍然是不可能的 我找到了一种根据找到的 Microsoft 代码示例禁用所有辅助显示器的方法here https msd
  • 在 lua 中加载 C++ 模块时出现“尝试索引字符串值”错误

    我正在尝试使用 lua 用 C 编写的函数 下面给出的是cpp文件 extern C include lua h include lauxlib h include lualib h static int add 5 lua State L
  • C# 模式匹配

    我对 C 有点陌生 我正在寻找一个字符串匹配模式来执行以下操作 我有一个像这样的字符串 该书将在 唐宁街 11 号接待处 并将由主要医疗保健人员参加 我需要创建一个 span 标签来使用 startIndex 和 length 突出显示一些
  • 检查另一种形式的线程是否仍在运行

    我有一个涉及两个窗体的 Windows 窗体应用程序 子表单用于将数据导出到 CSV 文件 并使用后台工作者写入文件 当这种情况发生时 我隐藏了表格 当后台工作程序运行时 父窗体仍然处于活动状态 因此即使后台工作程序正在写入文件 用户也可以

随机推荐

  • “grep”命令的退出状态代码

    The grep http linux die net man 1 grep手动在退出状态部分报告 EXIT STATUS The exit status is 0 if selected lines are found and 1 if
  • CTE 的意外结果

    我创建了一个使用多个 CTE 的复杂流程 主要用于递归分层工作 在小样本数据集上 一切都按预期进行 但是当我将代码应用于大数据集时 我收到了意外 且错误 的结果 我想我已经将范围缩小到了 CTE 递归 CTE 是在几个早期 CTE 中处理的
  • 在 Datalab 中查询 Hive 表时出现问题

    我已经创建了一个 dataproc 集群 其中包含更新的 init 操作来安装 datalab 一切正常 除了当我从 Datalab 笔记本查询 Hive 表时 我遇到了 hc sql select from invoices limit
  • Chrome 扩展:点击编辑当前网址,然后重定向到编辑后的网址

    我是一名心理学学生 我经常阅读论文 大学图书馆提供数据库的访问 但我每次都需要使用图书馆搜索引擎并登录 很烦人 我找到了一种避免跳转页面的方法 方法如下 我在Google Scholar中找到一篇论文后 在目标数据库地址末尾添加 ezp l
  • Symfony2 SonataAdminBundle 密码字段加密

    我有 FOSUserBundle 来管理我的用户 SonataAdminBundle 来管理我的网站 我有一个问题 每当我尝试更改 添加任何用户的密码时 密码都不会编码到sha512 但是当用户在 fosuserbundle 注册页面中注册
  • SQLite查询:获取一行的所有列(android)?

    这是架构 SQL查询是 从unjdat中选择 其中col 1 myWord 即 我想显示 col 1 为的行的所有列myWord int i String temp words new ArrayList
  • 如何使用正则表达式将缩写与其含义相匹配?

    我正在寻找与以下字符串匹配的正则表达式模式 一些示例文本 SET 演示了我正在寻找的内容 能源系统模型 ESM 用于寻找特定的最佳值 SCO 有人说计算机系统 CUST 很酷 夏天应该首选户外比赛 OUTS 我的目标是匹配以下内容 Some
  • 使用函数触发 chrome.browserAction.onClicked

    我想触发点击 以下代码正在侦听 chrome browserAction onClicked addListener function tab 原因是我有一个工作扩展 它正在后台脚本 上面的 addListener 中监听并在单击时执行一些
  • JavaScript 数组迭代返回多个值

    这太简单了 我感到困惑 我有以下内容 var x shrimp var stypes new Array shrimp crabs oysters fin fish crawfish alligator for t in stypes if
  • 动态改变任务重试次数

    重试任务可能毫无意义 例如 如果任务是传感器 并且由于凭据无效而失败 那么以后的任何重试都将不可避免地失败 如何定义可以决定重试是否合理的操作员 在 Airflow 1 10 6 中 决定任务是否应该重试的逻辑位于airflow model
  • SQLite 连接未出现在实体数据模型向导中(vs2015)

    我所做的是 1 在vs2015 Net Framework 4 6 中创建一个项目 2 从Nuget安装System Data SQLite 实际上是System Data SQLite 1 0 105 1 System Data SQLi
  • Spring JDBC 和 Firebird 数据库

    有没有人actually将 Firebird 2 1 与 Spring JDBC 一起使用 出于测试目的 我在 MySQL Postgres 和 Firebird 中设置了三个简单的单表数据库 我在连接 MySQL 或 Postgres 并
  • xml 中的 Android xml 引用不起作用

    我想将新的材料设计应用到我的 Android 应用程序中 但我的 xml 文件有一个小问题
  • 在SearchView中处理物理键盘的Enter键

    我在我的应用程序中实现了一个 SearchView 当我使用软键盘 使用查询文本监听器 https developer android com reference android widget SearchView OnQueryTextL
  • $watch 一个服务变量或者 $broadcast 一个带有 AngularJS 的事件

    我正在使用一项服务在控制器之间共享数据 当变量被修改时 应用程序必须更新 DOM 我找到了两种方法来做到这一点 您可以在此处查看代码 http jsfiddle net sosegon 9x4N3 7 http jsfiddle net s
  • Java - 通过对象数组调用扩展类中的函数

    我有一个对象数组 其中一些使用扩展版本 其中包含基类中不可用的函数 当数组是由基类定义时 如何通过数组调用该函数 Example Shape shapes new Shape 10 shapes 0 new Circle 10 10 rad
  • 解释 gcov 输出以识别基本块

    我使用 gcov 和手册中的选项 a all blocks When you use the a option you will get individual block counts 原始文件 include
  • 模拟静态 Eloquent 模型方法,包括 find()

    我一直在关注一般的 Mockery 和 PHP Unit 教程 包括 Jeffrey Way 的关于使用 PHP Unit 和 Mockery 测试 Laravel 的介绍 然而 对于这个应用程序 我们可以接受对 Eloquent 的依赖
  • 如何自动重新加载应用程序引擎开发服务器?

    我正在关注App Engine 网站上有关 Java 版 Google Cloud Endpoints 的教程 https developers google com appengine docs java endpoints getsta
  • TextBlock 文本在 DataGridCell 内未垂直居中

    我正在创建一个DataGrid在 C 中 来自代码隐藏 不是 XAML 但无论我尝试什么 我都无法让文本在数据单元格中垂直居中 我从以下开始 var CellStyle new Style typeof DataGridCell Sette