我正在实现一个 GridView,它通过单击列标题进行排序。我正在寻找标准解决方案之一,但它对我不起作用。
我有一个标题“P”,而单元格的内容和标题都应居中(对齐)。标题的标签“P”与绑定的“照片”不同。
<GridViewColumn Width="30" Header="P">
<GridViewColumn.HeaderContainerStyle>
<Style TargetType="{x:Type GridViewColumnHeader}">
<Setter Property="HorizontalContentAlignment" Value="Center"/>
</Style>
</GridViewColumn.HeaderContainerStyle>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Photo}" HorizontalAlignment="Center"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
处理列单击的代码如下(来自 Mircosoft 站点)。
假设有一个 DisplayMemberBinding
var columnBinding = headerClicked.Column.DisplayMemberBinding as Binding;
我没有,否则列标题和内容不居中。
否则它将以列的标签作为属性进行排序。
var sortBy = columnBinding?.Path.Path ?? headerClicked.Column.Header as string;
这也不起作用,因为我的标签是“P”,属性是“Photo”。
还有其他想法吗?
internal void HandleOverviewColumnHeaderClicked(GridViewColumnHeader headerClicked)
{
ListSortDirection direction;
if (headerClicked != null)
{
if (headerClicked.Role != GridViewColumnHeaderRole.Padding)
{
if (headerClicked != _lastHeaderClicked)
{
direction = ListSortDirection.Ascending;
}
else
{
if (_lastDirection == ListSortDirection.Ascending)
{
direction = ListSortDirection.Descending;
}
else
{
direction = ListSortDirection.Ascending;
}
}
var columnBinding = headerClicked.Column.DisplayMemberBinding as Binding;
var sortBy = columnBinding?.Path.Path ?? headerClicked.Column.Header as string;
Sort(sortBy, direction);
if (direction == ListSortDirection.Ascending)
{
headerClicked.Column.HeaderTemplate = _window.Resources["HeaderTemplateArrowUp"] as DataTemplate;
}
else
{
headerClicked.Column.HeaderTemplate = _window.Resources["HeaderTemplateArrowDown"] as DataTemplate;
}
// Remove arrow from previously sorted header
if (_lastHeaderClicked != null && _lastHeaderClicked != headerClicked)
{
_lastHeaderClicked.Column.HeaderTemplate = null;
}
_lastHeaderClicked = headerClicked;
_lastDirection = direction;
}
}
}
<GridViewColumn DisplayMemberBinding="{Binding MyData}">
<GridViewColumnHeader Content="MyHeader" Click="GridViewColumnHeader_Click" />
</GridViewColumn>
和
GridViewColumnHeader _lastHeaderClicked = null;
ListSortDirection _lastDirection = ListSortDirection.Ascending;
private void GridViewColumnHeader_Click(object sender, RoutedEventArgs e)
{
var headerClicked = e.OriginalSource as GridViewColumnHeader;
ListSortDirection direction;
if (headerClicked != null)
{
if (headerClicked.Role != GridViewColumnHeaderRole.Padding)
{
if (headerClicked != _lastHeaderClicked)
{
direction = ListSortDirection.Ascending;
}
else
{
if (_lastDirection == ListSortDirection.Ascending)
{
direction = ListSortDirection.Descending;
}
else
{
direction = ListSortDirection.Ascending;
}
}
var columnBinding = headerClicked.Column.DisplayMemberBinding as Binding;
var sortBy = columnBinding?.Path.Path ?? headerClicked.Column.Header as string;
Sort(sortBy, direction);
if (direction == ListSortDirection.Ascending)
{
headerClicked.Column.HeaderTemplate =
Resources["HeaderTemplateArrowUp"] as DataTemplate;
}
else
{
headerClicked.Column.HeaderTemplate =
Resources["HeaderTemplateArrowDown"] as DataTemplate;
}
// Remove arrow from previously sorted header
if (_lastHeaderClicked != null && _lastHeaderClicked != headerClicked)
{
_lastHeaderClicked.Column.HeaderTemplate = null;
}
_lastHeaderClicked = headerClicked;
_lastDirection = direction;
}
}
}
private void Sort(string sortBy, ListSortDirection direction)
{
ICollectionView dataView =
CollectionViewSource.GetDefaultView(lv.ItemsSource);
dataView.SortDescriptions.Clear();
SortDescription sd = new SortDescription(sortBy, direction);
dataView.SortDescriptions.Add(sd);
dataView.Refresh();
}
您可以使用 Tag 属性来设置排序依据的数据成员,因为 DisplayMemberBinding 和 Header 不包含您需要的名称。然后获取标签,类似于示例代码访问 DisplayMemberBinding 的方式。