簡體   English   中英

如何獲取XAML中定義的CollectionView

[英]How can I get the CollectionView that is defined in XAML

我想綁定到XAML中的ObservableCollection並在那里應用分組。 原則上,這很好。

<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>

然后數據綁定表達式變為ItemsSource="{Binding Source={StaticResource ResourceKey=cvs}}"而不是ItemsSource="{Binding Path=TestTemplates}"

起初,一切看起來都很酷,直到我想從視圖模型中刷新UI。 問題是, CollectionViewSource.GetDefaultView(TestTemplates)返回的視圖與應用分組的XAML中的視圖不同。 因此,我無法設置選擇或做任何有用的事情。

我可以通過將列表再次直接綁定到視圖模型的屬性並在代碼隱藏中設置分組來修復它。 但我對這個解決方案並不滿意。

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"));
    }
}

我認為,其原因已由John Skeet在此提供

盡管如此,我希望應該有一種方法來獲得正確的觀點。 我錯了嗎?

你不能這樣做嗎?

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

如果數據已連接,我認為將有更新的視圖。

我傾向於只從VM公開集合視圖而不是讓視圖定義它:

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

public ICollectionView EmployeesView
{
    get { ... }
}

這樣,您的VM就可以完全控制暴露給視圖的內容。 例如,它可以響應某些用戶操作更改排序順序。

找到了一種方法,基於J. Lennon的回答。 如果我通過my命令傳遞了可以訪問資源的東西,那么我可以在那里查找CollectionViewSource

在XAML(如上所述的CollectionViewResource )中:

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

在VM代碼中:

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

Execute是給RelayCommand的那個

這會回答這個問題,但我不太喜歡它。 意見?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM