在具有多个对象类型的树视图中处理SelectedItemChanged
本文关键字:视图 处理 SelectedItemChanged 类型 对象 | 更新日期: 2023-09-27 18:21:28
我正在尝试使用WPF树视图,但在获得所需的SelectedItemChanged时遇到了一些问题。我的设置目前是这样的:
A级:
[ImplementPropertyChanged]
public class TestCase
{
public string Name { get; set; }
public ObservableCollection<string> DataSets { get; set; }
}
然后,我在视图模型中创建了一个可观察的集合,其中包含几个测试用例,并将它们绑定到xaml,如下所示:
<TreeView
x:Name="TestCases"
ItemsSource="{Binding TestCases}"
Margin="0, 10, 0, 0">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectedItemChanged">
<i:InvokeCommandAction Command="{Binding SelectedTestCaseChangedCommand}" CommandParameter="{Binding ElementName=TestCases, Path=SelectedItem}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type testCases:TestCase}" ItemsSource="{Binding DataSets}">
<TextBlock Text="{Binding Name}" />
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type system:String}" >
<TextBlock Text="{Binding}" />
</DataTemplate>
</TreeView.Resources>
</TreeView>
这给了我一个很好的树形视图,看起来像这样:
Name
- DataSet
- DataSet
Name2
- DataSet
- etc
但问题是这部分:
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectedItemChanged">
<i:InvokeCommandAction Command="{Binding SelectedTestCaseChangedCommand}" CommandParameter="{Binding ElementName=TestCases, Path=SelectedItem}" />
</i:EventTrigger>
</i:Interaction.Triggers>
如果用户选择"名称",这很好,但如果他们单击数据集,当然会失败,因为它无法将字符串转换为TestCase。
所以我想在这里做几件事:
- 使它不能选择名称(只是展开它),这可能吗
- 当您选择一个数据集时,我希望获得具有所选数据集名称的"父"TestCase触发器。是否可以通过某种方式操纵命令参数来获得此信息
我想从代码后面通过手动检查应该很容易做到,但像这样的mvvm呢?
更新1我的视图模型中的命令方法:
[OnCommand("SelectedTestCaseChangedCommand")]
public void SelectedTestCaseChanged(TestCase testCase)
{
currentTestCase = testCase;
MessengerInstance.Send(new SelectedTestCaseChangedMessage(testCase));
}
假设您的命令是用您提到的RelayCommand
实现的,那么命令看起来像这样:
private ICommand _selectedTestCaseChangedCommand;
public ICommand SelectedTestCaseChangedCommand
{
get
{
if (_selectedTestCaseChangedCommand == null)
{
_selectedTestCaseChangedCommand = new RelayCommand<object>(SelectedTestCaseChanged);
}
return _selectedTestCaseChangedCommand;
}
}
您可以像以前那样定义SelectedTestCaseChanged
方法,但我建议使用参数类型作为object
,因为对象可以是一切。然后你只需要检查你的参数/选择的项目是什么。你有两种可能性。is
运算符或as
强制转换,后面有空检查。
private void SelectedTestCaseChanged(object obj)
{
if (obj is TestCase)
{
var testCase = (TestCase)obj;
// Work with testCase
}
if (obj is string)
{
// Do nothing or whatever
}
// Another option is
var testCase = obj as TestCase;
if (testCase != null)
{
//...
}
}
如果要获得TreeViewItem
的父级,则需要向上转到WPF的Visual Tree
,因为TreeViewItems
没有parent元素。
此SO问题中描述了该方法。
您可以获取选定元素的父元素,并使用父元素激发命令。我会在代码背后做这件事,但我在那里没有经验。
我不会禁用名称的选择,因为有了上面的解决方案,你就可以处理你不想要的情况。此外,用户感觉禁用的Names是一个bug。。
希望它能帮助