WPF - 应用 IValueConverter 进行集合绑定
WPF - Apply IValueConverter for collection binding
在我的 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;}
}
两者之间的主要区别 类 是生日 属性 的数据类型。一个是 DateTime
,另一个是 DateTimeOffset
。
我的应用程序中有以下代码。
IEnumerable<StudentDB> StudentDbs = GetAllStudentFromDB();
IEnumerable<Student> Students = new IEnumerable<Student> Students();
XAML:
<DataGrid ItemsSource="{Binding Students, Mode=TwoWay}" AutoGenerateColumns="True">
我需要在 DataGrid 中显示学生列表。
我无法绑定 StudentDbs,因为它具有 DateTimeOffset
类型 属性。
为了解决上述问题,我需要应用一个 Value Converter
,它将 StudentDb
对象转换为 Student
对象。
我知道如何实现 IValueConverter 接口 I。但我不知道如何将它应用于集合。
任何人都可以建议我解决这个问题的方法吗?
回答您的主要要求:DateTimeOffset class 有一个名为 DateTime 的 属性,表示当前 System.DateTimeOffset 的日期和时间目的。因此,您仍然可以将 StudentDbs 绑定为 DataGrid 的 Itemsource,并且可以直接将 BirthDate.DateTime 属性 绑定到 DataGrid 中的任意位置以实现您的要求。
您不需要值转换器。
更好的方法是通过 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>
来防止内存泄漏并允许更改集合。
值转换器必须应用于列。所以设置 AutoGenerateColumns="False" 并手动添加列:
<DataGrid.Columns>
<DataGridTextColumn Header="{lex:Loc ...}"
Binding="{Binding StarString, Converter={StaticResource ...}}">
当 AutoGenerating 为真时,使用 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();
};
}
}
请注意,您正在覆盖绑定。
在我的 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;}
}
两者之间的主要区别 类 是生日 属性 的数据类型。一个是 DateTime
,另一个是 DateTimeOffset
。
我的应用程序中有以下代码。
IEnumerable<StudentDB> StudentDbs = GetAllStudentFromDB();
IEnumerable<Student> Students = new IEnumerable<Student> Students();
XAML:
<DataGrid ItemsSource="{Binding Students, Mode=TwoWay}" AutoGenerateColumns="True">
我需要在 DataGrid 中显示学生列表。
我无法绑定 StudentDbs,因为它具有 DateTimeOffset
类型 属性。
为了解决上述问题,我需要应用一个 Value Converter
,它将 StudentDb
对象转换为 Student
对象。
我知道如何实现 IValueConverter 接口 I。但我不知道如何将它应用于集合。
任何人都可以建议我解决这个问题的方法吗?
回答您的主要要求:DateTimeOffset class 有一个名为 DateTime 的 属性,表示当前 System.DateTimeOffset 的日期和时间目的。因此,您仍然可以将 StudentDbs 绑定为 DataGrid 的 Itemsource,并且可以直接将 BirthDate.DateTime 属性 绑定到 DataGrid 中的任意位置以实现您的要求。
您不需要值转换器。
更好的方法是通过 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>
来防止内存泄漏并允许更改集合。
值转换器必须应用于列。所以设置 AutoGenerateColumns="False" 并手动添加列:
<DataGrid.Columns>
<DataGridTextColumn Header="{lex:Loc ...}"
Binding="{Binding StarString, Converter={StaticResource ...}}">
当 AutoGenerating 为真时,使用 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();
};
}
}
请注意,您正在覆盖绑定。