[C#.NET][WPF] 控制項的資料繫結(七) - CollectionViewSource(續)

[WPF] 控制項的資料繫結(七)–CollectionViewSource(續)

續上篇,我們使用了VS2010拖曳方式建立了DataGrid,可以發現這是用 CollectionViewSource 所處理,CollectionViewSource.Source屬性定義了資料來源(MemberList),CollectionViewSource.View 屬性也就是 CollectionView 類別繼承了 ICollectionView 介面,所以我們可以利用它來處理排序、過濾、群組化、巡覽等功能;ItemCollection 類別BindingListCollectionView 類別ListCollectionView 類別則是繼承 CollectionView 類別來的

image

 

這架構不就是MVVM嗎??

image

 

CollectionViewSource會依照來源,產生適當的View物件,比如說資料來源是MemberList.Group,因為我的Group屬性是用BindingList建立,此時的View屬性就是BindingListCollectionView,如下圖;

image

 

如果資料來源是清單那一類型(IList)的,應該就會使用ListCollectionView,想不到什麼時候會產生ItemCollection(抓頭)

 


規畫UI

image

在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 標題按下,出現小箭頭表示有排序

image

 

排序方法二:使用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<>

image

下圖使用List<>

image

 

排序方法三:針對集合進行排序,且重新綁定,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>

image

 

 

 

 


範例下載:

WpfBindingDemo.zip

若有謬誤,煩請告知,新手發帖請多包涵


Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET

Image result for microsoft+mvp+logo