none
WPF Datagrid 中文排序问题 RRS feed

  • 问题

  • 在使用Datagrid的过程中发现,当列中有中文时,单击列标题排序,得到的排序结果并不是按中文的拼音排序的(也没看出来是按什么规则排序的)。如下图所示:

    正常的升序:

    李四

    孙青阳

    王型号

    张三

    赵薇包

    正大海

    单击列标题排序后:

    孙青阳

    张三

    李四

    正大海

    王型号

    赵薇包

    代码如下:

    <Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
        <Grid>
            <DataGrid x:Name="dtg"/>
        </Grid>
    </Window>
    Class MainWindow 
    
        Public Sub New()
    
            ' 此调用是设计器所必需的。
            InitializeComponent()
    
            ' 在 InitializeComponent() 调用之后添加任何初始化。
            Dim ps As New List(Of People)
            ps.Add(New People With {.Name = "张三"})
            ps.Add(New People With {.Name = "李四"})
            ps.Add(New People With {.Name = "孙青阳"})
            ps.Add(New People With {.Name = "赵薇包"})
            ps.Add(New People With {.Name = "王型号"})
            ps.Add(New People With {.Name = "正大海"})
    
            ps = ps.OrderBy(Function(p) p.Name).ToList
    
            Me.dtg.ItemsSource = ps
        End Sub
    
    End Class
    
    Class People
        Public Property Name As String
            Get
                Return _Name
            End Get
            Set(ByVal value As String)
                _Name = value
            End Set
        End Property
        Private _Name As String
    
    End Class
    


    2014年4月10日 8:07

答案

  • 可以直接在DataGrid的Sorting事件里面控制排序,稍微修改了一点你的代码,你可以试一下:

    Class MainWindow
    
        Private ps As New List(Of People)
    
        Public Sub New()
    
            ' 此调用是设计器所必需的。
            InitializeComponent()
    
            ' 在 InitializeComponent() 调用之后添加任何初始化。
            ps.Add(New People With {.Name = "张三"})
            ps.Add(New People With {.Name = "李四"})
            ps.Add(New People With {.Name = "孙青阳"})
            ps.Add(New People With {.Name = "赵薇包"})
            ps.Add(New People With {.Name = "王型号"})
            ps.Add(New People With {.Name = "正大海"})
    
            ps = ps.OrderBy(Function(p) p.Name).ToList
    
            Me.dtg.ItemsSource = ps
    
            AddHandler dtg.Sorting, AddressOf Sort
        End Sub
    
        Private Sub Sort(ByVal sender As Object, ByVal e As DataGridSortingEventArgs)
            e.Handled = True '取消默认排序
            ps.Reverse()
            Me.dtg.Items.Refresh()
        End Sub
    End Class


    • 已编辑 lapheal 2014年4月10日 14:31
    • 已标记为答案 dextersunami 2014年4月11日 0:53
    2014年4月10日 14:30

全部回复

  • 不能使用他默认排序的 两种方法 一种是column里有个sortpath 你写一个list里包含了所有字和一个int型排序的index 你是用binding的方法。在外部排好序后index即是排序的顺序 sortpath指定index

    第二种方法是override onsorting事件 哪个argument 自己排序 然后重新赋值。

    中文排序方法:

    string[] arr = { "3","1","2","b","c","a","BB","A","C","阿尔巴尼亚", "一刀切", "二刀切" , "三刀切"};
                Array.Sort(arr);
    
                Console.WriteLine("按发音排序:");
                for (int i = arr.GetLowerBound(0); i <= arr.GetUpperBound(0); i++)
                    Console.WriteLine("[{0}]:\t{1}", i, arr.GetValue(i));
    // 输出的即为排序后的

    希望采纳谢谢。
    2014年4月10日 8:57
  • 没有其它更简单的办法了吗?
    2014年4月10日 9:56
  • 可以直接在DataGrid的Sorting事件里面控制排序,稍微修改了一点你的代码,你可以试一下:

    Class MainWindow
    
        Private ps As New List(Of People)
    
        Public Sub New()
    
            ' 此调用是设计器所必需的。
            InitializeComponent()
    
            ' 在 InitializeComponent() 调用之后添加任何初始化。
            ps.Add(New People With {.Name = "张三"})
            ps.Add(New People With {.Name = "李四"})
            ps.Add(New People With {.Name = "孙青阳"})
            ps.Add(New People With {.Name = "赵薇包"})
            ps.Add(New People With {.Name = "王型号"})
            ps.Add(New People With {.Name = "正大海"})
    
            ps = ps.OrderBy(Function(p) p.Name).ToList
    
            Me.dtg.ItemsSource = ps
    
            AddHandler dtg.Sorting, AddressOf Sort
        End Sub
    
        Private Sub Sort(ByVal sender As Object, ByVal e As DataGridSortingEventArgs)
            e.Handled = True '取消默认排序
            ps.Reverse()
            Me.dtg.Items.Refresh()
        End Sub
    End Class


    • 已编辑 lapheal 2014年4月10日 14:31
    • 已标记为答案 dextersunami 2014年4月11日 0:53
    2014年4月10日 14:30
  • 目前也只有这个办法了。谢谢啦!

    另外,不知你是否清楚,默认排序既然不是按中文拼音排序的,那又是按什么规则排序的呢?

    2014年4月11日 0:56
  • 是按内码排的序吧
    2014年4月16日 11:47