使 WPF 数据网格列绑定到转换器可排序
Make WPF datagrid column bound to converter sortable
我有 3 个数据网格列,它们绑定到不同的转换器,将对象字段转换为字符串。
现在使用 CollectionView 进行排序,如何使使用转换器的列可排序?
我首先使用 Entity Framework 数据库,所以我认为我无法将 DependencyProperty 添加到数据网格中显示的字段的对象。
也没有选择向数据库中的对象添加更多字段。
有没有优雅的解决方案?
XAML 示例代码:
<DataGridTextColumn Width="200" Header="Status" SortMemberPath="myPath">
<DataGridTextColumn.Binding>
<Binding Converter="{StaticResource fieldsToStringConverter}"/>
</DataGridTextColumn.Binding>
</DataGridTextColumn>
至于 C#,我有处理过滤和排序的 CollectionView,但目前仅对普通(非转换器)列进行排序:
ICollectionView datagridView = CollectionViewSource.GetDefaultView(myDataGrid.ItemsSource);
我选择的方案是:
我使用 DataGrid 的排序事件来检查对哪一列进行了排序。
如果单击使用转换器的列,我将保存当前排序方向并重新分配由创建新 CollectionView 的转换器排序的 DataGrid.Itemssource。然后将点击列的排序方向设置为保存的排序方向。
如果从数据库中添加或删除元素,这也很有效,因为如果当前排序是在使用转换器的列之一上,我可以使用排序事件函数作为刷新。为了清楚起见,这涉及一些未在下面示例中添加的代码。
XAML
<DataGrid x:Name="dataGrid" ... Sorting="dataGrid_Sorting">
...
<DataGridTextColumn Width="200" Header="Status" SortMemberPath="mySortMemberPath">
<DataGridTextColumn.Binding>
<Binding Converter="{StaticResource myConverter}"/>
</DataGridTextColumn.Binding>
</DataGridTextColumn>
C#
private void dataGrid_Sorting(object sender, DataGridSortingEventArgs e)
{
string sortMemberPath = e.Column.SortMemberPath;
if (sortMemberPath == null || sortMemberPath == "")
{
return;
}
IValueConverter converter = null;
switch (sortMemberPath)
{
case "mySortMemberPath":
converter = new myConverter();
break;
}
if (converter != null)
{
e.Handled = true;
ListSortDirection direction = (e.Column.SortDirection != ListSortDirection.Ascending) ? ListSortDirection.Ascending : ListSortDirection.Descending;
if (direction == ListSortDirection.Ascending)
{
dataGrid.ItemsSource = --sort my list with converter--
}
else
{
dataGrid.ItemsSource = --sort my list with converter--
}
datagridView = CollectionViewSource.GetDefaultView(dataGrid.ItemsSource);
e.Column.SortDirection = direction;
applyCollectionViewFilter();
}
}
我有 3 个数据网格列,它们绑定到不同的转换器,将对象字段转换为字符串。
现在使用 CollectionView 进行排序,如何使使用转换器的列可排序?
我首先使用 Entity Framework 数据库,所以我认为我无法将 DependencyProperty 添加到数据网格中显示的字段的对象。 也没有选择向数据库中的对象添加更多字段。
有没有优雅的解决方案?
XAML 示例代码:
<DataGridTextColumn Width="200" Header="Status" SortMemberPath="myPath">
<DataGridTextColumn.Binding>
<Binding Converter="{StaticResource fieldsToStringConverter}"/>
</DataGridTextColumn.Binding>
</DataGridTextColumn>
至于 C#,我有处理过滤和排序的 CollectionView,但目前仅对普通(非转换器)列进行排序:
ICollectionView datagridView = CollectionViewSource.GetDefaultView(myDataGrid.ItemsSource);
我选择的方案是:
我使用 DataGrid 的排序事件来检查对哪一列进行了排序。 如果单击使用转换器的列,我将保存当前排序方向并重新分配由创建新 CollectionView 的转换器排序的 DataGrid.Itemssource。然后将点击列的排序方向设置为保存的排序方向。
如果从数据库中添加或删除元素,这也很有效,因为如果当前排序是在使用转换器的列之一上,我可以使用排序事件函数作为刷新。为了清楚起见,这涉及一些未在下面示例中添加的代码。
XAML
<DataGrid x:Name="dataGrid" ... Sorting="dataGrid_Sorting">
...
<DataGridTextColumn Width="200" Header="Status" SortMemberPath="mySortMemberPath">
<DataGridTextColumn.Binding>
<Binding Converter="{StaticResource myConverter}"/>
</DataGridTextColumn.Binding>
</DataGridTextColumn>
C#
private void dataGrid_Sorting(object sender, DataGridSortingEventArgs e)
{
string sortMemberPath = e.Column.SortMemberPath;
if (sortMemberPath == null || sortMemberPath == "")
{
return;
}
IValueConverter converter = null;
switch (sortMemberPath)
{
case "mySortMemberPath":
converter = new myConverter();
break;
}
if (converter != null)
{
e.Handled = true;
ListSortDirection direction = (e.Column.SortDirection != ListSortDirection.Ascending) ? ListSortDirection.Ascending : ListSortDirection.Descending;
if (direction == ListSortDirection.Ascending)
{
dataGrid.ItemsSource = --sort my list with converter--
}
else
{
dataGrid.ItemsSource = --sort my list with converter--
}
datagridView = CollectionViewSource.GetDefaultView(dataGrid.ItemsSource);
e.Column.SortDirection = direction;
applyCollectionViewFilter();
}
}