如何在ViewModel中正确解析TreeviewItem的子元素

本文关键字:TreeviewItem 元素 ViewModel | 更新日期: 2023-09-27 18:03:46

我在WPF程序中有一个TreeView控件,它从MySQL服务器获取数据并显示databasestables:

Server
...Databases
    ...Tables

我想要的是当我点击Treeview中的一个项目时,我可以获得Server/Databases/Tables的名称。然而,经过几个小时的测试,我仍然无法获得名称。


HierarchicalDataTemplate of server

<HierarchicalDataTemplate 
     DataType="{x:Type local:ServerViewModel}"  
     ItemsSource="{Binding Children}">
    <StackPanel Orientation="Horizontal">
        <Image Width="16" Height="16" Margin="3,0" Source="Figures/server.png" />
        <TextBlock Text="{Binding ServerName}" />
    </StackPanel>
</HierarchicalDataTemplate>

其他两个是相似的,除了表的HierarchicalDataTemplate没有ItemsSource

当我使用MvvmLight模式时,我将SelectedItem作为CommandParameter传递给ViewModel:

<i:Interaction.Triggers>
    <i:EventTrigger EventName="SelectedItemChanged">
        <cmd:EventToCommand
            Command="{Binding tableSelected}"
            CommandParameter="{Binding SelectedItem,ElementName=MyTreeview}"
            PassEventArgsToCommand="True"/>
    </i:EventTrigger>
</i:Interaction.Triggers>
在ViewModel中,我声明了一个命令来处理SelectedItemChanged事件。我像下面这样实现了Execute()方法,但是它没有工作。每当我点击一个TreeviewItem,就会抛出一个未处理的异常System.Reflection.TargetInvocationException
private void GetSelectedItem(object parameter)
{
    var item = parameter as TreeViewItem;
    StackPanel stackpanel = (StackPanel)VisualTreeHelper.GetChild(item, 0);
    TextBlock textblock = (TextBlock)VisualTreeHelper.GetChild(stackpanel, 1);
    MessageBox.Show(textblock.Text);
}


命令

public ICommand tableSelected { get; private set; }//In the ViewModel

tableSelected = new RelayCommand<object>((obj) => GetSelectedItem(obj), (obj) => true);
//Implemented in the ViewModel's constructor

我在Stackoverflow上读过几个相关的帖子,比如我如何在WPF中获得TreeViewItem的内容?WPF:获得TreeViewItem的组成控件,但我仍然不能得到它的权利。请帮助,谢谢。

如何在ViewModel中正确解析TreeviewItem的子元素

我意识到我以前所做的是完全错误的。SelectedItem不是UI控件的集合,而纯粹是与DataType相同类型的实例。

<HierarchicalDataTemplate 
    DataType="{x:Type local:DatabaseViewModel}" 
    ItemsSource="{Binding Children}">
    <StackPanel Orientation="Horizontal">
        <Image Width="16" Height="16" Margin="3,0" Source="Figures/database.png" />
        <TextBlock Text="{Binding DatabaseName}" />
    </StackPanel>
</HierarchicalDataTemplate>
上面的代码是我的treeview的一部分。如果我点击一个使用这个模板的treeviewitem,我得到的是一个DatabaseViewModel实例,而不是一个StackPanel或它的孩子。