gpt4 book ai didi

c# - 如何在运行时动态更改 DataGrid 字符串列格式?

转载 作者:行者123 更新时间:2023-11-30 23:01:39 25 4
gpt4 key购买 nike

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

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 字符串列格式?

编辑

根据 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 类搜索方法中:

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();
}
}

最佳答案

How can DataGrid String column format be changed dynamically at runtime?

不能。您不能更改任何现有绑定(bind)的 StringFormat

与其设置列的 StringFormat 属性,您应该绑定(bind)到一个属性,该属性返回已格式化的字符串,并在格式化时引发此字符串的 PropertyChanged 事件变化:

public string FormattedDateOfBirth => DateOfBirth.ToShortDateString();

XAML:

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

With this answer, the capability to allow the user to sort the respective column BY DATE is lost (it is sorted by string rules instead).

只需将 SortMemberPath 属性设置为原始属性的名称即可:

<DataGridTextColumn ... SortMemberPath="DateOfBirth" Binding="{Binding FormattedDateOfBirth}" />

关于c# - 如何在运行时动态更改 DataGrid 字符串列格式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50926340/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com