2012-06-15 28 views
8

Tôi muốn liên kết với một số ObservableCollection trong XAML và cũng áp dụng nhóm đó. Về nguyên tắc, điều này làm việc tốt.Tôi làm cách nào để có được CollectionView được xác định trong XAML

<UserControl.Resources> 
    <CollectionViewSource x:Key="cvs" Source="{Binding Path=TestTemplates}"> 
     <CollectionViewSource.SortDescriptions> 
      <scm:SortDescription PropertyName="Title"/> 
     </CollectionViewSource.SortDescriptions> 
     <CollectionViewSource.GroupDescriptions> 
      <PropertyGroupDescription PropertyName="TestCategory"/> 
     </CollectionViewSource.GroupDescriptions> 
    </CollectionViewSource> 
</UserControl.Resources> 

Sau đó, biểu thức ràng buộc dữ liệu trở thành ItemsSource="{Binding Source={StaticResource ResourceKey=cvs}}" thay vì ItemsSource="{Binding Path=TestTemplates}".

Lúc đầu, mọi thứ có vẻ thú vị, cho đến khi tôi muốn làm mới giao diện người dùng từ mô hình chế độ xem. Vấn đề là, CollectionViewSource.GetDefaultView(TestTemplates) trả về một chế độ xem khác với chế độ xem từ XAML nơi áp dụng nhóm. Vì vậy, tôi không thể thiết lập lựa chọn hoặc làm bất cứ điều gì hữu ích với nó.

Tôi có thể sửa lỗi bằng cách liên kết trực tiếp danh sách với thuộc tính của mô hình chế độ xem và thiết lập nhóm trong mã sau. Nhưng tôi không hài lòng với giải pháp này.

private void UserControlLoaded(object sender, RoutedEventArgs e) 
{ 
    IEnumerable source = TemplateList.ItemsSource; 
    var cvs = (CollectionView)CollectionViewSource.GetDefaultView(source); 
    if (cvs != null) 
    { 
     cvs.SortDescriptions.Add(new SortDescription("Title", ListSortDirection.Ascending)); 
     cvs.GroupDescriptions.Add(new PropertyGroupDescription("TestCategory")); 
    } 
} 

Tôi giả sử, lý do là đã là given by John Skeet here.

Tuy nhiên, tôi hy vọng rằng sẽ có cách để có được chế độ xem phù hợp. Liệu tôi có sai?

+0

Bạn đang đi sai đường. Một máy ảo không có kiến ​​thức về chế độ xem. Nếu bạn muốn cập nhật chế độ xem, hãy đảm bảo thuộc tính mà nó liên kết là một ObservableCollection hoặc mã của bạn tăng NotifyPropertyChanged một cách rõ ràng khi sửa đổi bộ sưu tập. –

+0

@PanagiotisKanavos: Nội dung trong chế độ xem danh sách thực tế * là * trong 'ObservableCollection' và các mục trong giao diện người dùng thực hiện cập nhật về thay đổi thuộc tính. Nhưng nhóm không tôn trọng điều đó. Giải pháp được biết là buộc cập nhật, tức là 'CollectionViewSource.GetDefaultView (…) .Refresh'. – primfaktor

+0

Trong .NET 4.5, điều này sẽ được khắc phục với [ICollectionViewLiveShaping] (http://msdn.microsoft.com/en-us/library/system.componentmodel.icollectionviewliveshaping (v = vs.110) .aspx). – primfaktor

Trả lời

1

Tìm cách, dựa trên câu trả lời J. Lennon's. Nếu tôi chuyển một thứ gì đó có quyền truy cập vào các tài nguyên bằng lệnh của tôi, thì tôi có thể tra cứu số CollectionViewSource ở đó.

Trong XAML (CollectionViewResource như trên):

<Button Command="{Binding Command}" CommandParameter="{Binding RelativeSource={RelativeSource Self}}">Do it!</Button> 

Và trong mã VM:

private void Execute(object parm) 
{ 
    var fe = (FrameworkElement)parm; 
    var cvs = (CollectionViewSource)fe.FindResource("cvs"); 
    cvs.View.Refresh(); 
} 

Các Execute là một trong đó là trao cho các RelayCommand.

Điều này sẽ trả lời câu hỏi, nhưng tôi không thích nó lắm. Ý kiến?

+0

Vì điều này hoàn chỉnh hơn (và hoạt động) so với cơ sở của [J. Lennon] (http://stackoverflow.com/users/1128106/j-lennon), tôi đánh dấu (nhưng anh ta có tiền thưởng). – primfaktor

5

Tôi có xu hướng chỉ phơi bày quan điểm thu từ VM chứ không phải có cái nhìn định nghĩa nó:

public ICollection<Employee> Employees 
{ 
    get { ... } 
} 

public ICollectionView EmployeesView 
{ 
    get { ... } 
} 

Bằng cách đó VM của bạn có toàn quyền kiểm soát những gì được tiếp xúc với quan điểm. Ví dụ: có thể thay đổi thứ tự sắp xếp để phản hồi lại một số hành động của người dùng.

+0

Đó là một cách hay để làm điều đó, nhưng nó không trả lời câu hỏi. Tôi vẫn muốn biết. – primfaktor

+0

Ý bạn là gì bằng cách "làm mới chế độ xem" và tại sao bạn muốn làm điều đó? Nếu bộ sưu tập cơ bản được máy ảo của bạn trưng ra 'INotifyCollectionChanged' (chẳng hạn như với' ObservableCollection '), thì chế độ xem bộ sưu tập được tạo bởi chế độ xem của bạn sẽ được cập nhật, do đó giúp bạn tránh được sự cố" làm mới chế độ xem ". –

+1

Tôi phải có đủ điều kiện ở trên. Miễn là bạn chỉ thêm/xóa các mục, chế độ xem bộ sưu tập sẽ vẫn được sắp xếp. Nếu bạn đang sửa đổi thuộc tính cơ bản mà bạn sắp xếp, đó là một lý do hợp lệ tại sao bạn cần phải "làm mới". Nếu bạn thực sự muốn xem để tạo CV thay vì VM, thì bạn sẽ phải nâng cao một sự kiện trong máy ảo của bạn bất cứ khi nào khung nhìn sẽ làm mới. IMHO, nó chỉ là sạch hơn có VM xử lý tất cả, vì nó là logic kinh doanh anyways. –

5

Bạn không thể làm điều đó?

var _viewSource = this.FindResource("cvs") as CollectionViewSource; 

Nếu dữ liệu được kết nối, tôi cho rằng sẽ có một cái nhìn cập nhật.

+0

Điều này cũng được đưa ra bởi một đồng nghiệp. Vấn đề là trong VM, tôi không nhận được 'FindResource' của bất kỳ' FrameworkElement' (các assembly riêng biệt, chỉ có các máy ảo tham chiếu Vs). – primfaktor

+0

Khi câu trả lời của bạn đến gần nhất, bạn sẽ có tiền thưởng. Chi tiêu nó một cách khôn ngoan. ;-) – primfaktor

Các vấn đề liên quan