c# - 对包含不同类型单元格的 DataGrid 列进行排序会引发 ArgumentException

标签 c# wpf datagrid

我有一个绑定(bind)到项目集合的数据网格,这些项目有一个对象类型的字段,可以包含任何内容... bool 、字符串或任何内容。但是当我单击列标题进行排序时,会引发 ArgumentException。我的意思是这是完全有道理的,但我仍然如何避免这个问题。我想要的只是将所有内容转换为字符串并将它们作为字符串进行比较。使用转换器没有帮助。我无法更改 ViewModel 以对项目的属性执行 ToString,因此我需要一个仅查看解决方案。

这是一些示例代码:

XAML:

    <DataGrid
            ItemsSource="{Binding items}" 
            AutoGenerateColumns="False"  
            IsManipulationEnabled="False">
        <DataGrid.Columns>
            <DataGridTextColumn 
                    Header="Name"
                    IsReadOnly="True" 
                    Binding="{Binding Name}" />
            <DataGridTextColumn
                    Header="Content"              
                    IsReadOnly="True"
                    Binding="{Binding data, Converter={StaticResource toString}}"/>
        </DataGrid.Columns>
    </DataGrid>

C#:

public class MainViewModel : DependencyObject, INotifyPropertyChanged
{

    public MainViewModel()
    {
        items = new ObservableCollection<OneItem>();

        items.Add(new OneItem { Name = "Tom", Height = 180, Weight = 75, Class = 2, data = false });
        items.Add(new OneItem { Name = "Dick", Height = 182, Weight = 83, Class = 3, data = true });
        items.Add(new OneItem { Name = "Harry", Height = 182, Weight = 83, Class = 3, data = "Sting" });
    }

    public ObservableCollection<OneItem> items { get; private set; }

    public event PropertyChangedEventHandler PropertyChanged;
}

public class OneItem
{
    public string Name { get; set; }
    public double Height { get; set; }
    public double Weight { get; set; }
    public double Class { get; set; }

    public object data { get; set; }
}

异常(exception):

System.Windows.Data Error: 55 : Cannot sort by 'data' InvalidOperationException:'System.InvalidOperationException: Failed to compare two elements in the array. ---> System.ArgumentException: Object must be of type Boolean.
   at System.Boolean.CompareTo(Object obj)
   at System.Collections.Comparer.Compare(Object a, Object b)
   at MS.Internal.Data.SortFieldComparer.Compare(Object o1, Object o2)
   at System.Array.SorterGenericArray.SwapIfGreaterWithItems(Int32 a, Int32 b)
   at System.Array.SorterGenericArray.IntroSort(Int32 lo, Int32 hi, Int32 depthLimit)
   at System.Array.SorterGenericArray.IntrospectiveSort(Int32 left, Int32 length)
   --- End of inner exception stack trace ---
   at System.Array.SorterGenericArray.IntrospectiveSort(Int32 left, Int32 length)
   at System.Array.Sort(Array keys, Array items, Int32 index, Int32 length, IComparer comparer)
   at System.Array.Sort(Array array, IComparer comparer)
   at MS.Internal.Data.SortFieldComparer.SortHelper(ArrayList al, IComparer comparer)
   at MS.Internal.Data.DataExtensionMethods.Sort(IList list, IComparer comparer)
   at System.Windows.Data.ListCollectionView.PrepareLocalArray()
   at System.Windows.Data.ListCollectionView.RefreshOverride()
   at System.Windows.Data.CollectionView.RefreshInternal()
   at System.Windows.Data.CollectionView.Refresh()
   at System.Windows.Data.CollectionView.EndDefer()
   at System.Windows.Data.CollectionView.DeferHelper.Dispose()
   at System.Windows.Controls.ItemCollection.EndDefer()
   at System.Windows.Controls.ItemCollection.DeferHelper.Dispose()
   at System.Windows.Controls.DataGrid.DefaultSort(DataGridColumn column, Boolean clearExistingSortDescriptions)'

最佳答案

我像这样添加 DataDisplay 属性:

public class OneItem
{
    public string Name { get; set; }
    public double Height { get; set; }
    public double Weight { get; set; }
    public double Class { get; set; }

    public object data { get; set; }

    public object DataDisplay
    {
        get
        {
            if (data == null)
            {
                return string.Empty;
            }
            return data.ToString();
        }
    }
}

然后用DataDisplay替换数据并删除绑定(bind)中的Converter:

<Grid>
    <DataGrid
        ItemsSource="{Binding items}" 
        AutoGenerateColumns="False"  
        IsManipulationEnabled="False">
        <DataGrid.Columns>
            <DataGridTextColumn 
                Header="Name"
                IsReadOnly="True" 
                Binding="{Binding Name}" />
            <DataGridTextColumn
                Header="Content"              
                IsReadOnly="True"
                Binding="{Binding DataDisplay}"/>
        </DataGrid.Columns>
    </DataGrid>
</Grid>

如果您还想要转换器。让我知道:)

关于c# - 对包含不同类型单元格的 DataGrid 列进行排序会引发 ArgumentException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31074091/

相关文章:

c# - 将数据异步加载到数据网格中

WPF DataGrid,Ctrl+C 后复制到剪贴板,OnCopyingRowClipboardContent

c# - 如何从dll中导入一个类?

C# Winforms-WPF 互操作

c# - C#'s ` yield return` 为我制造了很多垃圾。有救吗?

c# - WPF:组合框的下拉列表突出显示了文本

c# - MVVM light 和运行时本地化更改

c# - 将行添加到 WPF 数据网格,其中列直到运行时才知道

c# - 如何从 Blazor 服务器端应用程序中的本地 Active Directory 实现身份验证?

c# - 字符串长度昂贵