如何在运行时动态更改 DataGrid String 列格式?

2024-06-05

我的 WPF 桌面应用程序提供了一个 UI 来搜索人员并在 DataGrid 中显示结果。 此外,用户可以在运行时更改语言(Current(UI)Culture)。

XAML 中的 DataGrid 定义是

<DataGrid Name="SearchResultTable" AutoGenerateColumns="False" MinHeight="200" CanUserSortColumns="False">
    <DataGrid.Columns>
        <DataGridTextColumn Header="lastName" Binding="{Binding LastName}" SortDirection="Ascending" IsReadOnly="True" DisplayIndex="0"/>
        <DataGridTextColumn Header="firstName" Binding="{Binding FirstName}"   IsReadOnly="True" DisplayIndex="1"/>
        <DataGridTextColumn Header="dateOfBirth" Binding="{Binding DateOfBirth }"   IsReadOnly="True" DisplayIndex="2"/>
    </DataGrid.Columns>
</DataGrid>

DateOfBirth 列内容的格式应根据所选语言而定。 c# 代码部分是:

DataGridTextColumn col = (DataGridTextColumn)SearchResultTable.Columns[2];
col.Binding.StringFormat = CultureInfo.CurrentUICulture.DateTimeFormat.ShortDatePattern;

此代码部分在创建 UI 类之后以及每次用户选择不同的语言时执行。 只要用户没有执行填充 DataGrid 的搜索,这种方法就可以正常工作。

但是一旦 DataGrid 第一次被填充

IList<Person> searchResult = // read data from database
SearchResultTable.ItemsSource = searchResult;

并且用户选择不同的语言会引发以下异常:

Binding cannot be changed after it has been used

那么,如何在运行时动态更改 DataGrid String 列格式呢?

EDIT

根据mm8的回答,我可以实施如下解决方案: 由于我可能不会更改 Person 类(业务领域!),因此我创建了一个以 Person 作为参考的辅助类

public class PersonHelper : INotifyPropertyChanged
{
    // ...
    private Person person = null;
    public String LastName { get => person.getLastName(); set => person.setLastName(LastName); }
    // ... 
    public string FormattedDateOfBirth => DateOfBirth.ToShortDateString();
    public void OnPropertyChanged(string name)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }
    // ...
}

在UI类Search方法中:

PersonObsColl = new ObservableCollection<PersonHelper>();
foreach (Person p in searchResult)
{
    PersonHelper ph = new PersonHelper(p);
    ph.PropertyChanged += new PropertyChangedEventHandler(PropertyFormattedDateOfBirthChanged);
    PersonObsColl.Add(ph);
}

在 CurrentUICulture 更改时调用的 UI 类方法中

foreach (PersonHelper ph in PersonObsColl)
    ph.OnPropertyChanged("FormattedDateOfBirth");

以及 UI 类中的 Handler

private void PropertyFormattedDateOfBirthChanged(object sender, PropertyChangedEventArgs e)
{
    if (sender is PersonHelper && e.PropertyName.Equals("FormattedDateOfBirth"))
    {
        // avoid to call invalidation for every search result line; can this be improved ?
        if(PersonObsColl.IndexOf((PersonHelper)sender) == PersonObsColl.Count -1)
            SearchResultTable.InvalidateVisual();
    }
}

如何在运行时动态更改 DataGrid String 列格式?

不可以。你无法改变StringFormat任何现有的绑定。

而不是设置StringFormat列的属性,您应该绑定到返回已格式化字符串的属性并引发PropertyChanged每当格式更改时都会发生此事件:

public string FormattedDateOfBirth => DateOfBirth.ToShortDateString();

XAML:

<DataGridTextColumn Header="dateOfBirth" Binding="{Binding FormattedDateOfBirth}" IsReadOnly="True" DisplayIndex="2"/>

有了这个答案,允许用户按日期对相应列进行排序的功能就丢失了(而是按字符串规则排序)。

这只是设置的问题SortMemberPath属性改为原始属性的名称:

<DataGridTextColumn ... SortMemberPath="DateOfBirth" Binding="{Binding FormattedDateOfBirth}" />
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在运行时动态更改 DataGrid String 列格式? 的相关文章

  • 如何使用MemoryCache代替Timer来触发一个方法?

    以下方法通过等待已运行操作的结果来处理并发请求 对数据的请求可能会使用相同 不同的凭据同时出现 对于每组唯一的凭据 最多可以有一个GetCurrentInternal呼叫正在进行中 当准备就绪时 该呼叫的结果将返回给所有排队的服务员 pri
  • 使用 Unity 在构造函数中使用属性依赖注入

    好的 我在基类中定义了一个依赖属性 我尝试在其派生类的构造函数内部使用它 但这不起作用 该属性显示为 null Unity 在使用 container Resolve 解析实例后解析依赖属性 我的另一种选择是将 IUnityContaine
  • 使用Physics.Raycast 和Physics2D.Raycast 检测对象上的点击

    我的场景中有一个空的游戏对象 带有 2D 组件盒碰撞器 我将脚本附加到该游戏对象 void OnMouseDown Debug Log clic 但是当我点击我的游戏对象时 没有任何效果 你有什么想法 如何检测我的盒子碰撞器上的点击 使用光
  • 如何在 C# 中从 UNIX 纪元时间转换并考虑夏令时?

    我有一个从 unix 纪元时间转换为 NET DateTime 值的函数 public static DateTime FromUnixEpochTime double unixTime DateTime d new DateTime 19
  • XamlReader.Load 在后台线程中。是否可以?

    WPF 应用程序具有从单独的文件加载用户控件的操作 使用XamlReader Load method StreamReader mysr new StreamReader pathToFile DependencyObject rootOb
  • 单元测试一起运行时失败,单独运行时通过

    所以我的单元测试遇到了一些问题 我不能只是将它们复制并粘贴到这里 但我会尽力而为 问题似乎是 如果我一项一项地运行测试 一切都会按预期进行 但如果我告诉它一起运行测试 则 1 5 将通过 TestMethod public void Obj
  • 读取文件特定行号的有效方法。 (奖励:Python 手册印刷错误)

    我有一个 100 GB 的文本文件 它是来自数据库的 BCP 转储 当我尝试导入它时BULK INSERT 我在第 219506324 行上收到一个神秘错误 在解决此问题之前 我想看看这一行 但可惜的是我最喜欢的方法 import line
  • 单击 form2 上的按钮触发 form 1 中的方法

    我对 Windows 窗体很陌生 我想知道是否可以通过单击表单 2 中的按钮来触发表单 1 中的方法 我的表格 1 有一个组合框 我的 Form 2 有一个 保存 按钮 我想要实现的是 当用户单击表单 2 中的 保存 时 我需要检查表单 1
  • 将 Excel 导入到 Datagridview

    我使用此代码打开 Excel 文件并将其保存在 DataGridView 中 string name Items string constr Provider Microsoft Jet OLEDB 4 0 Data Source Dial
  • 如何将自定义 JSON 文件添加到 IConfiguration 中?

    我正在使用 asp net Autofac 我正在尝试加载自定义 JSON 配置文件 并基于该文件创建 实例化 IConfiguration 实例 或者至少将我的文件包含到默认情况下构建的 IConfiguration asp net 中
  • 将 log4net 与 Autofac 结合使用

    我正在尝试将 log4net 与 Autofac 一起使用 我粘贴了这段代码http autofac readthedocs org en latest examples log4net html http autofac readthed
  • std::async 与重载函数

    可能的重复 std bind 重载解析 https stackoverflow com questions 4159487 stdbind overload resolution 考虑以下 C 示例 class A public int f
  • HttpWebRequest 在第二次调用时超时

    为什么以下代码在第二次 及后续 运行时超时 代码挂在 using Stream objStream request GetResponse GetResponseStream 然后引发 WebException 表示请求已超时 我已经尝试过
  • (de)从 CSV 序列化为对象(或者最好是类型对象的列表)

    我是一名 C 程序员 试图学习 C 似乎有一些内置的对象序列化 但我在这里有点不知所措 我被要求将测试数据从 CSV 文件加载到对象集合中 CSV 比 xml 更受青睐 因为它更简单且更易于人类阅读 我们正在创建测试数据来运行单元测试 该集
  • gcc 的配置选项如何确定默认枚举大小(短或非短)?

    我尝试了一些 gcc 编译器来查看默认枚举大小是否很短 至少一个字节 强制使用 fshort enums 或无短 至少 4 个字节 强制使用 fno short enums user host echo Static assert 4 si
  • 为什么在setsid()之前fork()

    Why fork before setsid 守护进程 基本上 如果我想将一个进程与其控制终端分离并使其成为进程组领导者 我使用setsid 之前没有分叉就这样做是行不通的 Why 首先 setsid 将使您的进程成为进程组的领导者 但它也
  • Process.Start() 方法在什么情况下返回 false?

    From MSDN https msdn microsoft com en us library e8zac0ca v vs 110 aspx 返回值 true 表示有新的进程资源 开始了 如果由 FileName 成员指定的进程资源 St
  • 有没有办法强制显示工具提示?

    我有一个验证字段的方法 如果无法验证 该字段将被清除并标记为红色 我还希望在框上方弹出一个工具提示 并向用户显示该值无效的消息 有没有办法做到这一点 并且可以控制工具提示显示的时间 我怎样才能让它自己弹出而不是鼠标悬停时弹出 If the
  • 编译时“strlen()”有效吗?

    有时需要将字符串的长度与常量进行比较 例如 if line length gt 2 Do something 但我试图避免在代码中使用 魔法 常量 通常我使用这样的代码 if line length gt strlen Do somethi
  • 在客户端系统中安装后桌面应用程序无法打开

    我目前正在使用 Visual Studio 2017 和 4 6 1 net 框架 我为桌面应用程序创建了安装文件 安装程序在我的系统中完美安装并运行 问题是安装程序在其他计算机上成功安装 但应用程序无法打开 edit 在客户端系统中下载了

随机推荐