绑定到 TreeViewItem 的父 DataContext,但 TreeView 的 DataContext 用于最顶层的项目



我有一个使用单个HierarchicalDataTemplateTreeView。我知道如何绑定到HierarchicalDataTemplate中父TreeViewItem的属性:

<Button
Command="{Binding DataContext.RemoveCommand,
RelativeSource={RelativeSource AncestorLevel=2,
AncestorType=TreeViewItem}}"
CommandParameter="{Binding ElementId}" />

但是,这当然不适用于最顶层的项目,因为没有祖先TreeViewItem- 在这里,我想使用TreeView本身的DataContext。如何将命令绑定到树视图最顶层元素的TreeViewDataContext?如有必要,可以假定视图模型具有与表示每个树项的分层视图模型同名的属性。

这是我修改后的MainWindow.xaml,基于Elmish.WPF(GitHub上的存储库(的SubModelCollection示例,它展示了我认为如何解决问题。正如我在对OP的评论中提到的,我在这个解决方案中遇到了一个新问题,但我希望它可以在不费吹灰之力的情况下得到解决。我有一种感觉,这是一个仍然存在的微不足道的问题。

我在这里的目的是将一个分层数据模板用于顶级项目,另一个用于所有其他项目。令我惊讶的是,就正确操作数据而言,它看起来实际上有效,并且按钮在所有级别上都有效,但 WPF 对正在发生的事情并不满意。当我在二级节点下方添加、删除或移动子节点时,它们会在视觉上折叠,VS 中的"输出"窗格有话要说:

"System.Windows.Data 错误: 4 : 找不到使用引用 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ItemsControl', AncestorLevel='1'' 进行绑定的源。绑定表达式:路径=水平内容对齐;数据项=空;目标元素是"树视图项"(名称="(;目标属性为"水平内容对齐"(类型为"水平对齐"( ">

在引入 SharedPart 之前,我遇到了同样的错误,所以我认为这不是导致它的原因。

这是MainWindow.xaml,我修改的唯一文件。

<Window
x:Class="Elmish.WPF.Samples.SubModelCollection.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Single counter" Height="800" Width="1000"
WindowStartupLocation="CenterScreen">
<Window.Resources>
<DataTemplate x:Key="SharedPart">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding CounterId}" Width="250" Margin="10,5,10,5" />
<TextBlock Text="{Binding CounterValue, StringFormat='Counter value: {0}'}" Width="100" Margin="0,5,10,5" />
<Button Command="{Binding Decrement}" Content="-" Margin="0,5,10,5" Width="30" />
<Button Command="{Binding Increment}" Content="+" Margin="0,5,10,5" Width="30" />
<Button Command="{Binding Reset}" Content="Reset" Margin="0,5,10,5" Width="50" />
<TextBlock Text="{Binding StepSize, StringFormat='Step size: {0}'}" Margin="0,5,10,5" />
<Slider Value="{Binding StepSize}" TickFrequency="1" Maximum="10" Minimum="1" IsSnapToTickEnabled="True" Width="100" Margin="0,5,10,5" />
<Button Command="{Binding AddChild}" Content="Add child" Margin="0,5,10,5" />
</StackPanel>
</DataTemplate>
<HierarchicalDataTemplate x:Key="Level2Data" ItemsSource="{Binding Path=ChildCounters}">
<StackPanel Orientation="Horizontal">
<ContentPresenter Content="{Binding}" ContentTemplate="{StaticResource SharedPart}"/>
<Button
Command="{Binding DataContext.Remove, RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}, AncestorLevel=2}}"
CommandParameter="{Binding CounterId}"
Content="×" Margin="0,5,10,5" Width="20" />
<Button
Command="{Binding DataContext.MoveUp, RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}, AncestorLevel=2}}"
CommandParameter="{Binding CounterId}"
Content="↑" Margin="0,5,10,5" Width="20" />
<Button
Command="{Binding DataContext.MoveDown, RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}, AncestorLevel=2}}"
CommandParameter="{Binding CounterId}"
Content="↓" Margin="0,5,10,5" Width="20"/>
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate x:Key="Level1Data" ItemsSource="{Binding Path=ChildCounters}" ItemTemplate="{StaticResource Level2Data}">
<StackPanel Orientation="Horizontal">
<ContentPresenter Content="{Binding}" ContentTemplate="{StaticResource SharedPart}"/>
<Button
Command="{Binding DataContext.Remove, RelativeSource={RelativeSource FindAncestor, AncestorType=TreeView}}"
CommandParameter="{Binding CounterId}"
Content="×" Margin="0,5,10,5" Width="20" />
<Button
Command="{Binding DataContext.MoveUp, RelativeSource={RelativeSource FindAncestor, AncestorType=TreeView}}"
CommandParameter="{Binding CounterId}"
Content="↑" Margin="0,5,10,5" Width="20" />
<Button
Command="{Binding DataContext.MoveDown, RelativeSource={RelativeSource FindAncestor, AncestorType=TreeView}}"
CommandParameter="{Binding CounterId}"
Content="↓" Margin="0,5,10,5" Width="20"/>
</StackPanel>
</HierarchicalDataTemplate>
</Window.Resources>
<StackPanel Margin="0,20,0,10">
<Button Command="{Binding AddCounter}" Content="Add counter" Width="150" Margin="0,0,0,20" />
<TreeView ItemsSource="{Binding Counters}" ItemTemplate="{StaticResource Level1Data}">
</TreeView>
</StackPanel>

最新更新