我在WPF中创建了一个listview控件,并成功完全绑定了Icollectionview
ObservableCollection<object>
对象。我的listview列是动态创建的。
我必须对listview进行排序和分组,但它无法正常工作。
我的代码如下。
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>
答案 0 :(得分:4)
由于您使用的是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上的每个Remove
或Add
都会刷新ListView。通常,如果您想在一个步骤中应用多个排序,这是不需要的。然后你应该用以下内容包围该块:
using(MyList.DeferRefresh())
{
//put your changes in sorting and grouping here
}