[WPF] 控制項的資料繫結(七)–CollectionViewSource(續)
續上篇,我們使用了VS2010拖曳方式建立了DataGrid,可以發現這是用 CollectionViewSource 所處理,CollectionViewSource.Source屬性定義了資料來源(MemberList),CollectionViewSource.View 屬性也就是 CollectionView 類別繼承了 ICollectionView 介面,所以我們可以利用它來處理排序、過濾、群組化、巡覽等功能;ItemCollection 類別、BindingListCollectionView 類別、ListCollectionView 類別則是繼承 CollectionView 類別來的
這架構不就是MVVM嗎??
CollectionViewSource會依照來源,產生適當的View物件,比如說資料來源是MemberList.Group,因為我的Group屬性是用BindingList建立,此時的View屬性就是BindingListCollectionView,如下圖;
如果資料來源是清單那一類型(IList)的,應該就會使用ListCollectionView,想不到什麼時候會產生ItemCollection(抓頭)
規畫UI
在Loaded事件裡加入以下程式碼:
CollectionViewSource _ViewSource = null;
MemberList _MemberList = new MemberList();
BindingListCollectionView _CollectionView = null;
private void Window_Loaded(object sender, RoutedEventArgs e)
{
this._ViewSource = this.FindResource("memberListGroupViewSource") as CollectionViewSource;
this._ViewSource.Source = this._MemberList.Group;
this.labCount.Content = "/" + this._MemberList.Group.Count;
this.txtCurrent.Text = "1";
this._CollectionView = (BindingListCollectionView)this._ViewSource.View;
this._CollectionView.CurrentChanged += new EventHandler(_CollectionView_CurrentChanged);
}
void _CollectionView_CurrentChanged(object sender, EventArgs e)
{
BindingListCollectionView collection = (BindingListCollectionView)sender;
this.txtCurrent.Text = (collection.CurrentPosition + 1).ToString();
this.labCount.Content = "/" + this._MemberList.Group.Count;
}
BindingListCollectionView 類別 與 ListCollectionView 類別 都擁有的功能。
巡覽功能:上一頁、下一頁、第一頁、最後一頁
private void btnNext_Click(object sender, RoutedEventArgs e)
{
this._CollectionView.MoveCurrentToNext();
if (this._CollectionView.IsCurrentAfterLast)//若是在最後一筆之後
this._CollectionView.MoveCurrentToLast();
}
private void btnPrevious_Click(object sender, RoutedEventArgs e)
{
this._CollectionView.MoveCurrentToPrevious();
if (this._CollectionView.IsCurrentBeforeFirst)//若是在第一筆之前
this._CollectionView.MoveCurrentToFirst();
}
private void btnLast_Click(object sender, RoutedEventArgs e)
{
this._CollectionView.MoveCurrentToLast();
}
private void btnFirst_Click(object sender, RoutedEventArgs e)
{
this._CollectionView.MoveCurrentToFirst();
}
新增、刪除功能
private void btnAddNew_Click(object sender, RoutedEventArgs e)
{
this._CollectionView.AddNew();
}
private void btnDelete_Click(object sender, RoutedEventArgs e)
{
this._CollectionView.Remove(this._CollectionView.CurrentItem);
}
排序功能:
預設情況下沒有辦法直接對 BindingListCollectionView 類別 進行排序,不過我們仍然有辦法處理。
排序方法一:操作UI,ListCollectionView 類別 適用
使用DataGrid的Column 標題按下,出現小箭頭表示有排序
排序方法二:使用this._CollectionView.SortDescriptions,ListCollectionView 類別 適用
private void btnSort_Click(object sender, RoutedEventArgs e)
{
if (this._CollectionView.SortDescriptions.Count > 0)
this._CollectionView.SortDescriptions.Clear();
if (!this._CollectionView.CanSort)
return;
this._CollectionView.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
}
因為是使用BindingList原故,所以DataGrid無法進行排序,所以只要將來源改成List<>就可以進行排序,[.NET][Winform] 利用集合排序,重現 DataGridView 資料繫結後的排序
下圖使用BindingList<>
下圖使用List<>
排序方法三:針對集合進行排序,且重新綁定,BindingListCollectionView 類別 與 ListCollectionView 類別 適用
所以利用集合排序的方式處理,我選用了LINQ的方式
private void btnSort_Click(object sender, RoutedEventArgs e)
{
var query = this._MemberList.Group.OrderBy(o => o.Name);
this._MemberList.Group = query.ToList();
this._ViewSource.Source = this._MemberList.Group;
}
排序方法四:定義XAML,ListCollectionView 類別 適用
1.匯入命名空間:xmlns:System.ComponentModel="clr-namespace:System.ComponentModel;assembly=WindowsBase"
2.定義CollectionViewSource.SortDescriptions區段,這段設定在BindingList<>無效
<CollectionViewSource x:Key="memberListGroupViewSource" Source="{Binding Path=Group, Source={StaticResource memberListViewSource}}" >
<CollectionViewSource.SortDescriptions>
<System.ComponentModel:SortDescription PropertyName="Name"/>
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
範例下載:
若有謬誤,煩請告知,新手發帖請多包涵
Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET