繁体   English   中英

排序ObservableCollection <Class> 列表框中的数据

[英]Sorting ObservableCollection<Class> data in ListBox

我的程序有两个ListBoxes。 他们通过AddRemove按钮彼此交换项目。 在添加和删除过程中,我想使用OrderBy对项目进行排序(按ID),但我不知道如何使用此查询结果。 我该如何使用OrderBy

在此处输入图片说明

看来OrderBy正在运作,但我只是不知道放在哪里:

IEnumerable<GraphViewModel> query_orderBy_ID = RightListBoxItems.OrderBy(value => value.ID);
??? = query_orderBy_ID;

...好吧,然后我将右边放回原来的收藏中:

RightListBoxItems = (ObservableCollection<GraphViewModel>)RightListBoxItems.OrderBy(value => value.ID).ToList();

错误CS0030:无法将类型“ System.Collections.Generic.List”转换为“ System.Collections.ObjectModel.ObservableCollection”

我认为强制转换可以解决此问题,但是它不起作用。

这是我的代码:

MainWindow.xaml.cs

编辑:Add_Button_Click()添加了query_orderBy_ID循环,并使其更简单,抱歉:

using Sorting_List_with_OrderBy.ViewModel;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;

namespace Sorting_List_with_OrderBy
{
    public partial class MainWindow : Window
    {
        public ObservableCollection<GraphViewModel> LeftListBoxItems { get; set; }
            = new ObservableCollection<GraphViewModel>();
        public ObservableCollection<GraphViewModel> RightListBoxItems { get; set; }
            = new ObservableCollection<GraphViewModel>();

        ObservableCollection<string> TestItems = new ObservableCollection<string>();
        IEnumerable<GraphViewModel> query_orderBy_ID;

        public MainWindow()
        {
            InitializeComponent();

            DataContext = this;

            TestItems.Add("T0");
            TestItems.Add("T1");
            TestItems.Add("T2");

            foreach (var test in TestItems.Select((k, i) => new { kvp = k, index = i }))
            {
                LeftListBoxItems.Add(new GraphViewModel(test.index, test.kvp));
            }
        }

        private void Add_Button_Click(object sender, RoutedEventArgs e)
        {
            foreach (var graphViewModel in LeftListBox.SelectedItems.Cast<GraphViewModel>().ToList())
            {
                LeftListBoxItems.Remove(graphViewModel);

                // 1st Attempt: I don't know where to put this result to ...
                query_orderBy_ID = RightListBoxItems.OrderBy(value => value.ID);

                // 2nd Attempt: This substitution fails ...
                //RightListBoxItems = (ObservableCollection<GraphViewModel>)RightListBoxItems.OrderBy(value => value.ID).ToList();

                RightListBoxItems.Add(graphViewModel);
            }
            query_orderBy_ID = RightListBoxItems.OrderBy(value => value.ID);
            foreach (GraphViewModel orderBy_ID in query_orderBy_ID)
            {
                MessageBox.Show(orderBy_ID.ID + ": " + orderBy_ID.TestName);
            }
        }

        private void Remove_Button_Click(object sender, RoutedEventArgs e)
        {
            foreach (var graphViewModel in RightListBox.SelectedItems.Cast<GraphViewModel>().ToList())
            {
                RightListBoxItems.Remove(graphViewModel);
                LeftListBoxItems.Add(graphViewModel);
            }
        }

    }
}

MainWindow.xaml

<Window x:Class="Sorting_List_with_OrderBy.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Sorting_List_with_OrderBy"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="600">
    <Grid>
        <ListBox Margin="15,158,0,69.8" x:Name="LeftListBox" HorizontalAlignment="Left" Width="184" Background="AntiqueWhite"
                 SelectionMode="Extended" ItemsSource="{Binding LeftListBoxItems}" DisplayMemberPath="TestName"/>

        <Button x:Name="Add_Button" Height="26" Margin="232,196,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="80"
                 Click="Add_Button_Click" Content="Add &gt;&gt;"/>
        <Button x:Name="Remove_Button" Margin="230,267,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="82"
                 Click="Remove_Button_Click" Height="26" Content="&lt;&lt; Remove"/>

        <ListBox Margin="343,158,0,71.8" x:Name="RightListBox" HorizontalAlignment="Left" Width="200" Background="AntiqueWhite"
                 SelectionMode="Extended" ItemsSource="{Binding RightListBoxItems}" DisplayMemberPath="TestName"/>
    </Grid>
</Window>

ViewModel / GraphViewModel.cs

namespace Sorting_List_with_OrderBy.ViewModel
{
    public class GraphViewModel
    {
        public int ID { get; }
        public string TestName { get; }

        public GraphViewModel(int id, string testName) => (ID, TestName) = (id, testName);
    }
}

这个问题的主要目的是对我的ListBox进行排序,因此ListBox项应该以正确的顺序[ T0T1T2 ]进行排序。 我相信,如果上述问题得到解决,他们将会得到解决。

任何建议都会有所帮助。 谢谢。

OrderBy将返回IOrderedEnumerable<T> ,该IOrderedEnumerable<T>根据排序键进行排序。 原始集合保持其原始状态。 因此,您需要使用已排序的结果集合覆盖原始集合:

this.LeftListBoxItems = new ObservableCollection<GraphViewModel>(this.LeftListBoxItems.OrderBy(value => value.ID))

为了使ObservableCollection在添加/删除项目时自动排序,可以通过将SortDescriptionICollectionView来对其进行一次配置(例如,从构造函数中进行配置):

CollectionViewSource.GetDefaultView(this.LeftListBoxItems)
  .SortDescriptions
  .Add(new SortDescription(nameof(GraphViewModel.ID), ListSortDirection.Ascending));

注意
WPF绑定到集合的ICollectionView ,而不是直接绑定到集合。 ICollectionView上设置SortDescription只会对该ICollectionView排序。 这意味着UI看起来已排序,而基础集合保持未排序(或按不同规则排序)。

暂无
暂无

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

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