在 WPF 中使用 SortDescription 时出现问题 - int 和 string 不是 IComparable?

发布于 2024-10-05 11:53:54 字数 1577 浏览 0 评论 0原文

我在使用 SortDescription 时遇到问题。我发现了一些有关该问题的线程,例如如果您想按未实现 IComparable 的类型(例如用户定义的类)进行排序,但这不是我的情况。

我有一个类,它有两个属性:字符串 ID 和 int Value。我们称之为项目吧! 我有一个观点:

<UserControl> <!-- ... -->
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>

        <Button Click="Button_Click"
                Content="Sort by ID"
                Grid.Row="0"/>
        <Button Click="Button_Click1"
                Content="Sort by Value"
                Grid.Row="1"/>
        <DockPanel Grid.Row="2">
            <ItemsControl x:Name="mItemsControl"
                          ItemsSource="{Binding Items}"><!-- The type of Items is ObservableCollection<Item> -->
                <!-- ... -->
            </ItemsControl>
        </DockPanel>
    </Grid>
</GroupBox>

EventHandlers 是这样的:

private void Button_Click(object sender, RoutedEventArgs e)
    {
        mItemsControl.Items.SortDescriptions.Add(new SortDescription("ID", ListSortDirection.Ascending); //Exception here
    }
private void Button_Click1(object sender, RoutedEventArgs e)
    {
        mItemsControl.Items.SortDescriptions.Add(new SortDescription("Value", ListSortDirection.Ascending); //...and here as well
    }

我得到 InvalidOperationException 因为它“无法比较数组中的两个元素。”,这是因为这两个元素都没有实现 IComparable。 也就是说,我无法理解,因为我可以比较整数以及字符串。

感谢您的任何想法!

I have a problem in using SortDescription. I've found some thread about the problem, like if you want to sort by a type that doesn't implement IComparable, like a user defined class, but it's not my case.

I have a class, that has two properties: string ID, and int Value. Let's call it Item!
And I have a view:

<UserControl> <!-- ... -->
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>

        <Button Click="Button_Click"
                Content="Sort by ID"
                Grid.Row="0"/>
        <Button Click="Button_Click1"
                Content="Sort by Value"
                Grid.Row="1"/>
        <DockPanel Grid.Row="2">
            <ItemsControl x:Name="mItemsControl"
                          ItemsSource="{Binding Items}"><!-- The type of Items is ObservableCollection<Item> -->
                <!-- ... -->
            </ItemsControl>
        </DockPanel>
    </Grid>
</GroupBox>

EventHandlers are like these:

private void Button_Click(object sender, RoutedEventArgs e)
    {
        mItemsControl.Items.SortDescriptions.Add(new SortDescription("ID", ListSortDirection.Ascending); //Exception here
    }
private void Button_Click1(object sender, RoutedEventArgs e)
    {
        mItemsControl.Items.SortDescriptions.Add(new SortDescription("Value", ListSortDirection.Ascending); //...and here as well
    }

I get InvalidOperationException because it "Failed to compare two elements in the array.", and it is because neither of the elements implement IComparable.
And that is, what I can't understand, as I can compare ints, as well as strings.

Thanks for any idea!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

帅气尐潴 2024-10-12 11:54:52

它是您排序所依据的列中项目的运行时类型。属性 ID 和 Value 必须都是派生 IComparable 的类型。

我假设您并没有尝试做一些聪明的事情,并将不同的运行时类型(所有具有名为 ID 和 Value 的属性)放入 Items 列表中。您可以使用 WPF 来做类似的动态事情,但这就是它失败的一个例子。

字符串实现 IComparable http://msdn.microsoft.com/en-us/库/system.string.aspx

Its in the runtime type of the items in the columns you are sorting by. The properties ID and Value must both be types deriving IComparable.

I am assuming you are not trying to do something clever and putting different runtime types all with properties named ID and Value into the Items list. You can use WPF to do dynamic things like that, but this is one example of where it will fall down.

String implement IComparable http://msdn.microsoft.com/en-us/library/system.string.aspx

蓝颜夕 2024-10-12 11:54:47

我不知道这是否相关,但是当我尝试对列进行排序时,我在 DataGridView 上收到了相同的错误,这就是原因:

单元格的值必须具有相同的类型才能进行比较。如果您有三行,其中两行具有相同类型的值,但另一行没有值,如果具有值的两行已设置为对象作为单元格的值,则无法比较该值没有值的行将是一个空字符串。为了排序,您必须将要排序的列中所有单元格的值设置为字符串值。

I don't know if this is relevant, but I received the same error on a DataGridView when trying to sort a colum and this was the reason:

The value of the cell must by of the same type for it to be compared. If you have three rows and in two of the row you have values of the same type but the other row does not have a value it cannot compare it if the two rows which have value have been set to an object as the value for the cell in the row which has not value will be an empty string. In order to sort you will have to set the Value as string value for all the cell in the column that you are sorting.

南薇 2024-10-12 11:54:38

这对我来说效果很好,所以你在代码的其他部分做错了。将您所做的与下面的示例进行比较。

XAML:

<Window x:Class="SortDemo.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <StackPanel>
        <Button Click="OnSort" Content="Sort by ID" Tag="ID"/>
        <Button Click="OnSort" Content="Sort by Value" Tag="Value"/>
        <ItemsControl Name="_itemsControl" ItemsSource="{Binding Path=Items}" />
    </StackPanel>
</Window>

隐藏代码:

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;

namespace SortDemo
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();

            Items = new ObservableCollection<Item>();
            Items.Add(new Item() { ID = "AAA", Value = 2 });
            Items.Add(new Item() { ID = "BBB", Value = 1 });

            DataContext = this;
        }

        public ObservableCollection<Item> Items { get; private set; }

        private void OnSort(object sender, RoutedEventArgs e)
        {
            string sortProperty = (sender as FrameworkElement).Tag as string;
            _itemsControl.Items.SortDescriptions.Clear();
            _itemsControl.Items.SortDescriptions.Add(new SortDescription(sortProperty, ListSortDirection.Ascending)); 
        }
    }

    public class Item
    {
        public string ID { get; set;}
        public int Value { get; set; }

        public override string ToString()
        {
            return ID + " " + Value;
        }
    }
}

This works fine for me so you are doing something wrong in other parts of your code. Compare what you do with below sample.

XAML:

<Window x:Class="SortDemo.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <StackPanel>
        <Button Click="OnSort" Content="Sort by ID" Tag="ID"/>
        <Button Click="OnSort" Content="Sort by Value" Tag="Value"/>
        <ItemsControl Name="_itemsControl" ItemsSource="{Binding Path=Items}" />
    </StackPanel>
</Window>

Code behind:

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;

namespace SortDemo
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();

            Items = new ObservableCollection<Item>();
            Items.Add(new Item() { ID = "AAA", Value = 2 });
            Items.Add(new Item() { ID = "BBB", Value = 1 });

            DataContext = this;
        }

        public ObservableCollection<Item> Items { get; private set; }

        private void OnSort(object sender, RoutedEventArgs e)
        {
            string sortProperty = (sender as FrameworkElement).Tag as string;
            _itemsControl.Items.SortDescriptions.Clear();
            _itemsControl.Items.SortDescriptions.Add(new SortDescription(sortProperty, ListSortDirection.Ascending)); 
        }
    }

    public class Item
    {
        public string ID { get; set;}
        public int Value { get; set; }

        public override string ToString()
        {
            return ID + " " + Value;
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文