将子节点绑定到集合视图源



这是我的数据结构:

MyViewModel
Docs (ObservableCollection<Doc>)
Specs (ObservableCollection<Spec>)

即 ViewModel 有一个名为DocsObservableCollection,它是Doc对象的集合,反过来,每个Doc对象都有一个Spec对象的集合。名为position的属性(在 Doc 和 Spec 类中均可用)存储每个文档/规范的逻辑位置。

我现在需要将此结构绑定到TreeView.我需要始终对文档和规范进行排序(TreeView 支持节点的拖放重新排列),因此直接绑定在这里不起作用。

因此,我使用CollectionViewSource在运行时执行排序。

<CollectionViewSource x:Key="DocumentsCVS" Source="{Binding Docs}">
<CollectionViewSource.SortDescriptions>
<componentmodel:SortDescription PropertyName="position" />
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>

并在我的树视图中使用它:

<TreeView ItemsSource="{Binding Source={StaticResource DocumentsCVS}}">

目前为止,一切都好。树视图显示我的文档已排序。

但从这里开始,事情变得令人困惑。如何/在哪里为我的规格创建CollectionViewSource?我尝试在我的HierarchicalDataTemplate中这样做:

<HierarchicalDataTemplate>
<HierarchicalDataTemplate.ItemsSource>
<Binding>
<Binding.Source>
<CollectionViewSource Source="{Binding Specs}">
<CollectionViewSource.SortDescriptions>
<componentmodel:SortDescription PropertyName="position" />
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
</Binding.Source>
</Binding>
</HierarchicalDataTemplate.ItemsSource>
</HierarchicalDataTemplate>    

但这行不通。TreeView中只列出了文档,里面没有子文档。我的直觉是,CollectionViewSource可能与父母TreeViewItem生活在同一个DataContext中。

还是别的什么?

编辑

下面是我的树视图的完整 XAML:

<TreeView ItemsSource="{Binding Source={StaticResource DocumentsCVS}}" 
PresentationTraceSources.TraceLevel="High">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate DataType="{x:Type vm:DocumentVM}">
<HierarchicalDataTemplate.ItemsSource>
<Binding>
<Binding.Source>
<CollectionViewSource Source="{Binding Specs}">
<CollectionViewSource.SortDescriptions>
<componentmodel:SortDescription PropertyName="position" />
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
</Binding.Source>
</Binding>
</HierarchicalDataTemplate.ItemsSource>
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate DataType="{x:Type vm:SpecVM}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<fa:ImageAwesome Grid.Column="0" Icon="PuzzlePiece" Width="16" Margin="3,3,6,3" Foreground="Orange" />
<Label Grid.Column="1" Content="{Binding name}" />
</Grid>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<fa:ImageAwesome Icon="FileWordOutline" Height="16" Margin="3,3,6,3" Foreground="Crimson" />
<Label Grid.Column="1" Content="{Binding name}" />
</Grid>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
<CollectionViewSource Source="{Binding Specs}">

源代码上的绑定不知道去哪里寻找数据上下文(没有"框架导师")。我已经把这个踢了一下。我找不到定义 CollectionViewSource 的地方,它从模板继承 DataContext。

我确实找到了解决方案。

C#

public class SortConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var view = CollectionViewSource.GetDefaultView(value);
view.SortDescriptions.Add(new SortDescription((string)parameter, ListSortDirection.Ascending));
return view;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}

XAML

<HierarchicalDataTemplate 
DataType="{x:Type vm:DocumentVM}" 
ItemsSource="{Binding Specs, Converter={StaticResource SortConverter}, ConverterParameter=position}"
>

通过为转换器提供多个 PropertyName/SortDirection 属性或 SortDescriptions 集合,可以使这更有用。你可以把它变成一个标记扩展。您也可以只在视图模型属性中创建集合视图。

相关内容

  • 没有找到相关文章

最新更新