繁体   English   中英

如何对WPF DataGrid中除第一列以外的所有内容进行排序

[英]How to sort all but first column in WPF DataGrid

我有一个WPF DataGrid,它的第一列中包含一个数字,即“排名”或“位置”。 我想要的是,当我单击列以根据该列对表进行排序时,第一列保持原样。

例如:

Position  Name   Games   Points    PPG
1         John   2       10        5
2         Mary   3       12        4

按游戏降序排序时,

Position  Name   Games   Points    PPG
1         Mary   3       12        4
2         John   2       10        5

有没有办法做到这一点? DataColumn似乎没有任何此类属性,并且FreezeColumnsCount始终始终将它们保留在视图中,但不会阻止它们与其余数据一起被排序。

我将为此使用ValueConverter 我无法确切告诉您如何执行此操作,但是,您要查看的是DataGrid上的属性ItemContainerGenerator

将一个DataGrid属性添加到您的ValueConverter中,以便您可以从Convert方法访问该属性。 现在,在convert中,您将需要调用ContainerFromItem来获取UI对象,然后IndexFromContainer来获取行的索引。 我确定您会遇到一些问题,但这应该可以开始。

这样做的好处是您不必自己进行排序。 这将依赖于DataGrid使用的添加到ICollectionViewSortDescriptions (如果未绑定到它,则将自动为您创建)。

编辑

这是请求的代码示例。 我自己不需要这样做,但这就是我要开始的地方。

这是转换后的建议值的外观

public ItemPositionValueConverter : IValueConverter
{
    public DataGrid DataGrid { get; set; }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null)
        {
            return null;
        }

        if (DataGrid == null)
        {
            return null;
        }

        ItemContainerGenerator generator = DataGrid.ItemContainerGenerator;
        return generator.IndexFromContainer(generator.ContainerFromItem(value));
    }

    //you probably don't need ConvertBack put it is provided for completeness
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        int? index = value as int?

        if (index == null)
        {
            return null
        }

        if (DataGrid == null)
        {
            return null;
        }

        ItemContainerGenerator generator = DataGrid.ItemContainerGenerator;
        return generator.ItemFromContainer(generator.ContainerFromIndex(index.Value));
    }
}

现在要使用此功能做类似的事情。

<UserControl>
    <UserControl.Resources>
        <ItemPositionValueConverter x:Key=ItemPositionValueConverter"
                                    DataGrid="{Binding ElementName=MyDataGrid}" />
    </UserControl.Resources>

    <DataGrid x:Name="MyDataGrid" ItemsSource="{Binding ....}">
        <DataGrid.Columns> 
            <DataGridTextColumn Header="Position"
                                Binding="{Binding Converter={StaticResource ItemPositionValueConverter}}"/>
        </DataGrid.Columns>
</UserControl>

注意,使用此解决方案,无需手动将排序添加到ICollectionView。 当您单击列标题时,将自动应用排序。

**免责声明:此代码已经过测试说明,可能无法完全按照所述功能运行。 它是此处的提供程序,用于演示所需的逻辑。 因此,它可能包含错别字或错误。 任何尝试使用此代码的人都应执行自己的测试,以验证其是否适合他们的需求。

http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/ffd7037d-dd77-44ec-9011-d0d43d5706aa/中,我刚刚找到了一个示例(来自Adbie的回答),以表达我在评论中的建议:

<DataGrid LoadingRow="dg_LoadingRow">
    <DataGrid.RowHeaderTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Path=Header, RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}}" />
        </DataTemplate>
    </DataGrid.RowHeaderTemplate>
</DataGrid>


private void dg_LoadingRow(object sender, DataGridRowEventArgs e)
{
    e.Row.Header = (e.Row.GetIndex() + 1).ToString();
}


OP编辑:
我刚刚验证了它即使没有绑定也可以工作。 cs代码很好,但是在XAML中,您只需要

<DataGrid LoadingRow="dg_LoadingRow" />

新答案:

所以我的最后答案显然不符合标准,我已经做过一些研究,看来您可以按照以下方式进行:

 Dim view As ICollectionView = CollectionViewSource.GetDefaultView(ListViewName.Items)
 view.SortDescriptions.Add(New SortDescription("Field To Sort By", 0))

哪里

  • “要排序的字段”是列名
  • #是方向0升序,1是降序

注意:

  • 您必须在更改列表中同一列的排序顺序之间调用view.SortDescriptions.Clear()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM