WPF - 将 IValueConverter 应用于集合绑定

本文关键字:集合 绑定 应用于 IValueConverter WPF | 更新日期: 2023-09-27 18:32:13

在我的WPF应用程序中,我有类Student和StudentDB。

class StudentDB
{
   int StudentId{get;set;}
   string  Name{get;set;}
   string  City{get;set;}
   DateTimeOffset BirthDate{get;set;}
}
class Student
{
   int StudentId{get;set;}
   string  Name{get;set;}
   string  City{get;set;}
   DateTime BirthDate{get;set;}
}

两个类之间的主要区别在于 Birthday 属性的数据类型。 一个是DateTime,另一个是DateTimeOffset

我的应用程序中有以下代码。

IEnumerable<StudentDB> StudentDbs = GetAllStudentFromDB();
IEnumerable<Student> Students = new IEnumerable<Student> Students();

XAML:

<DataGrid ItemsSource="{Binding Students, Mode=TwoWay}" AutoGenerateColumns="True">

我需要在数据网格中显示学生列表。我无法绑定 StudentDbs,因为它具有 DateTimeOffset 类型属性。

为了解决上述问题,我需要应用一个Value Converter,它将StudentDb对象转换为Student对象。

我知道如何实现 IValueConverter 接口 I。但我不知道如何将它应用于集合。

谁能给我一个解决方案来解决这个问题?

WPF - 将 IValueConverter 应用于集合绑定

你不需要值转换器。

更好的方法是通过 LINQ 或 ViewModel 中的其他方式将StudentDB转换为Student,然后将Student对象的集合绑定到DataGrid

IEnumerable<StudentDB> StudentDbs = GetAllStudentFromDB();
IEnumerable<Student> Students = new StudentDbs.Select(student => ConvertToDto(student));
private Student ConvertToDto(StudentDB)
{
    return new Student 
    { 
        StudentId = StudentId, 
        Name = Name, 
        City = City, 
        BirthDate = BirthDate.DateTime 
    };
}
<DataGrid ItemsSource="{Binding Students, Mode=TwoWay}" AutoGenerateColumns="True">

此外,最好使用 ObservableCollection<T> 来防止内存泄漏并允许集合更改。

满足

主要要求的答案:DateTimeOffset 类有一个名为 DateTime 的属性,该属性表示当前 System.DateTimeOffset 对象的日期和时间。因此,您仍然可以将 StudentDbs 绑定为 DataGrid 的 Itemsource,并且可以直接将 BirthDate.DateTime 属性绑定到 DataGrid 中的任何位置,以满足您的要求。

值转换器 musst 应用于列。因此,设置 AutoGenerateColumns="False" 并手动添加列:

<DataGrid.Columns>
<DataGridTextColumn Header="{lex:Loc ...}"
Binding="{Binding StarString, Converter={StaticResource ...}}">

当自动生成为 true 时,请使用 DataGrid 的 AutoGeneratingColumn 事件。 在 XAML 中添加:

<DataGrid ItemsSource="{Binding Students, Mode=TwoWay}" AutoGenerateColumns="True" AutoGeneratingColumn="StartListGrid_OnAutoGeneratingColumn"

在代码隐藏中添加以下内容:

private void StartListGrid_OnAutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
    {
        if (e.PropertyName == "BirthDate" && e.Column is DataGridTextColumn)
        {
            var textColumn = e.Column as DataGridTextColumn;
            textColumn.Binding = new Binding(e.PropertyName)
            {
                Converter = new MyValueConverter();
            };
        }
    }

请注意,您正在覆盖绑定。