xaml - 绑定到 TreeViewItem 的父 DataContext 但 TreeView 的 DataContext 用于最顶层的项目
问题描述
我有一个TreeView
使用单个HierarchicalDataTemplate
. TreeViewItem
我知道如何在a中绑定到父级的属性HierarchicalDataTemplate
:
<Button
Command="{Binding DataContext.RemoveCommand,
RelativeSource={RelativeSource AncestorLevel=2,
AncestorType=TreeViewItem}}"
CommandParameter="{Binding ElementId}" />
但是,这当然不适用于最顶层的项目,因为没有祖先TreeViewItem
- 在这里,我想使用DataContext
它TreeView
本身。如何将命令绑定到树视图最顶层元素的TreeView
's ?DataContext
如有必要,您可以假设视图模型具有与表示每个树项的分层视图模型同名的属性。
解决方案
这是我基于 Elmish.WPF 的 SubModelCollection 示例(GitHub 上的存储库)修改后的 MainWindow.xaml,它演示了我认为我是如何解决问题的。正如我在对 OP 的评论中提到的,我遇到了这个解决方案的一个新问题,但我希望它可以在不费力的情况下解决。我有一种感觉,这是一个微不足道的问题。
我的意图是一个 HierarchicalDataTemplate 将用于顶级项目,另一个用于所有其他项目。令我惊讶的是,它看起来实际上可以正确处理数据,并且按钮可以在所有级别上工作,但是 WPF 对正在发生的事情并不满意。当我在其下方添加、删除或移动子节点时,二级节点会在视觉上折叠,并且 VS 中的“输出”窗格有一些要说明的内容:
“System.Windows.Data 错误:4:找不到与引用'RelativeSource FindAncestor,AncestorType='System.Windows.Controls.ItemsControl',AncestorLevel='1''的绑定源。BindingExpression:Path=HorizontalContentAlignment;DataItem=null;目标元素是'TreeViewItem'(名称='');目标属性是'HorizontalContentAlignment'(类型'HorizontalAlignment')“
在介绍 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>
推荐阅读
- ruby - Ruby - 将 ldap objectGUID 转换为可读形式
- javascript - 在 Android 上的 Flutter webview 中启用位置
- reactjs - 如何使用 REST API 在 React JS 中实现分页
- python - 合并熊猫数据框列时出错
- r - 如何获得置信区间?
- php - woocommerce 在字符串之前删除
- r - 在 R 中创建治疗概率图(模糊回归不连续性)
- .net - 从内存中删除凭据(由 FormUrlEncodedContent 引起)
- java - 具有多个参数的 Java JMH 运行方法
- python - Time.Sleep 替代方案和如果 Keyboard.is_pressed 替代方案?需要能够打破循环/返回主