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

时间:2018-08-14 14:10:20

标签: xaml data-binding treeview datacontext

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

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

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

1 个答案:

答案 0 :(得分:0)

这是我根据Elmish.WPF(在GitHub上的仓库)的SubModelCollection示例修改后的MainWindow.xaml,该示例演示了我以为我解决了这个问题。正如我在对OP的评论中提到的那样,此解决方案遇到了一个新问题,但我希望可以不费吹灰之力解决它。我觉得这仍然是一个琐碎的问题。

我的目的是将一个HierarchicalDataTemplate用于顶层项目,将另一个用于所有其他项目。令我惊讶的是,看起来它实际上可以正确地处理数据,并且按钮可以在所有级别上使用,但是WPF对发生的事情不满意。当我在子节点下面添加,删除或移动子节点时,第二层的节点会在视觉上崩溃,而VS中的“输出”窗格可以告诉您以下信息:

“ System.Windows.Data错误:4:找不到参考'RelativeSource FindAncestor,AncestorType ='System.Windows.Controls.ItemsControl',AncestorLevel ='1''的绑定源。BindingExpression:Path = Horizo​​ntalContentAlignment; DataItem = null;目标元素为“ TreeViewItem”(名称=“);目标属性为“ Horizo​​ntalContentAlignment”(类型为“ Horizo​​ntalAlignment”) “

在介绍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>