【问题标题】:sort and group Icollectionview in WPF在 WPF 中对 Icollectionview 进行排序和分组
【发布时间】:2013-11-13 05:55:37
【问题描述】:

我在 WPF 中创建了一个列表视图控件,并成功地完全绑定了 IcollectionviewObservableCollection<object> 对象。我的列表视图列是动态创建的。 我必须对我的列表视图进行排序和分组,但它无法正常工作。 我的代码如下。

private void LaodList()
{
    dt = new DataTable();
    dt.Columns.Add("AA", typeof(string));
    dt.Columns.Add("BB", typeof(string));
    dt.Columns.Add("cc", typeof(string));
    dt.Rows.Add("12", "66",11);
    dt.Rows.Add("33", "44",22);
    dt.AcceptChanges();


    GridView gv = new GridView();
    //gv.AllowsColumnReorder = true;

    List<string> myItemsCollection = new List<string>();
    for (int i = 0; i < dt.Columns.Count; i++)
    {
        GridViewColumn col = new GridViewColumn();
        col.Header = dt.Columns[i].ColumnName;
        col.DisplayMemberBinding = new Binding(string.Format("[{0}]", i));
        gv.Columns.Add(col);
        myItemsCollection.Add(col.Header.ToString());
    }

    LvItems.View = gv;
    this.Source = CollectionViewSource.GetDefaultView(LoadItems(dt)) ;  
    LvItems.DataContext = this.Source;
    cmbGroups.ItemsSource = myItemsCollection;
}


public ObservableCollection<object> LoadItems(DataTable dt)
{
    ObservableCollection<object> items = new ObservableCollection<object>();
    foreach (DataRow dataRow in dt.Rows)
    {
         items.Add(dataRow.ItemArray);
    }

    return items;
 }

//sort////////////////////////

private void ListView_Click(object sender, RoutedEventArgs e)
{

    GridViewColumnHeader currentHeader = e.OriginalSource as GridViewColumnHeader;
    if (currentHeader != null && currentHeader.Role != GridViewColumnHeaderRole.Padding)
    {
        if (this.Source.SortDescriptions.Count((item) => item.PropertyName.Equals(currentHeader.Column.Header.ToString())) > 0)
        {
            SortDescription currentPropertySort = this.Source
                        .SortDescriptions
                        .First<SortDescription>(item => item.PropertyName.Equals(currentHeader.Column.Header.ToString()));

                    //Toggle sort direction.
                    ListSortDirection direction =
                        (currentPropertySort.Direction == ListSortDirection.Ascending) ?
                        ListSortDirection.Descending : ListSortDirection.Ascending;

                    //Remove existing sort
                    this.Source.SortDescriptions.Remove(currentPropertySort);
                    this.Source.SortDescriptions.Insert(0, new SortDescription(currentHeader.Column.Header.ToString(), direction));
                }
                else
                {
                    this.Source.SortDescriptions.Insert(0, new SortDescription(currentHeader.Column.Header.ToString(), ListSortDirection.Ascending));
                }

                this.Source.Refresh();
            }

        }

//group////////////////////

private void btnGroup_Click(object sender, RoutedEventArgs e)
{
            this.Source.GroupDescriptions.Clear();

            PropertyInfo pinfo = typeof(object).GetProperty(cmbGroups.Text);
            if (pinfo != null)
                this.Source.GroupDescriptions.Add(new PropertyGroupDescription(pinfo.Name));

}

WPF代码如下

<ListView ItemsSource="{Binding}" x:Name="LvItems" ButtonBase.Click="ListView_Click" IsSynchronizedWithCurrentItem="True" Grid.Row="1" Margin="0,22,0,43">
        <ListView.GroupStyle>
            <GroupStyle>
                <GroupStyle.HeaderTemplate>
                    <DataTemplate>
                        <TextBlock FontSize="15" FontWeight="Bold" Text="{Binding}"/>
                    </DataTemplate>
                </GroupStyle.HeaderTemplate>
            </GroupStyle>
        </ListView.GroupStyle>

    </ListView>

【问题讨论】:

    标签: c# wpf observablecollection icollectionview


    【解决方案1】:

    由于您使用的是 WPF,因此您应该使用 DataBindings。将您的 ICollectionView 公开为属性并对其进行绑定

    public ICollectionView MyList
    {
        get
        {
            if(_mylist == null)
                _mylist = CollectionViewSource.GetDefaultView(observableCollection);
            return _mylist;
        }
    }
    

    在 XAML 中,您按如下方式应用绑定

    <ListView ItemsSource="{Binding Path=MyList}"/>
    

    现在您对该属性应用排序

    MyList.SortDescriptions.Remove(...);
    MyList.SortDescriptions.Add(...);
    
    MyList.GroupDescription.Add(...);
    

    这样做的缺点是,SortDescription 或 GroupDescription 上的每个 RemoveAdd 都会刷新 ListView。如果您想在一个步骤中应用许多排序,通常这是不需要的。然后你应该用以下内容括起来:

    using(MyList.DeferRefresh())
    {
        //put your changes in sorting and grouping here
    }
    

    【讨论】:

    • 我认为问题在于分组中设置的绑定属性。当我在运行时添加数据和列时,如何在运行时也设置分组绑定。请指教。
    • 您也可以在代码隐藏中执行此操作,使用列表视图的事件或使用命令。顺便说一句,如果您使用 DataGrid,则不需要实现排序,因为 DataGrid 控件已经允许排序。
    • 分组怎么样?可以举个例子吗?
    • 您将在此处找到完整的 HowTo:Group, Sort in DataGrid
    猜你喜欢
    • 2011-09-04
    • 2011-04-13
    • 2011-06-26
    • 1970-01-01
    • 1970-01-01
    • 2021-08-13
    • 2014-06-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多