在WPF中对Icollectionview进行排序和分组 [英] sort and group Icollectionview in WPF

查看:558
本文介绍了在WPF中对Icollectionview进行排序和分组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have created a listview control in WPF and has success fully bound Icollectionview object of ObservableCollection<object>. My listview columns are created dynamically. I have to sort and group my listview and it is not working properly. My code is as below.

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>

推荐答案

由于使用的是WPF,因此应使用DataBindings.将您的ICollectionView公开为属性并绑定在其上

Since you are using WPF you shall use DataBindings. Expose your ICollectionView as a property and bind on it

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

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

In the XAML you apply the binding as follows

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

现在您对该属性进行排序

And now you apply the sorting on that property

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

MyList.GroupDescription.Add(...);

这有一个缺点,即SortDescription或GroupDescription上的每个RemoveAdd都会刷新ListView.通常,如果要一步进行多种排序,则不需要这样做.然后,您应使用以下代码将该块括起来:

This has the drawback that every Remove or Add on a SortDescription or GroupDescription will refresh the ListView. Normally this is unwanted if you want to apply many sortings in one step. Then you should enclose the block with following:

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

这篇关于在WPF中对Icollectionview进行排序和分组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆