我正在尝试使用 WPF TreeView ,但在获取我想要的 SelectedItemChanged 时遇到了一些问题。我的设置目前是这样的:
一类:
[ImplementPropertyChanged]
public class TestCase
{
public string Name { get; set; }
public ObservableCollection<string> DataSets { get; set; }
}
然后我在我的 View 模型中创建一个带有几个测试用例的可观察集合,并将它们绑定(bind)到 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>
这给了我一个很好的 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。
所以我想在这里做几件事:
我想通过做一些手动检查从后面的代码中完成它应该很容易,但是像这样的 mvvm 呢?
更新 1 我的 View 模型中的命令方法:
[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
的父级你需要上Visual Tree
WPF,因为 TreeViewItems
没有父元素。方法描述in this SO Question .
您可以获取所选元素的父元素并使用父元素触发命令。我会在后面的代码中执行此操作,但我在那里没有经验。
我不会禁用名称的选择,因为通过上面的解决方案,您可以处理您不想要的情况。此外,用户觉得禁用的名称是一个错误..
希望能帮助到你
关于c# - 在具有多种对象类型的 TreeView 中处理 SelectedItemChanged,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33652451/