如何在ViewModel中正确解析TreeviewItem的子项?

时间:2014-05-18 02:54:24

标签: c# wpf mvvm treeview

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

Server
...Databases
    ...Tables

我想要的是当我点击Treeview中的某个项目时,我可以获得Server/Databases/Tables'名称。但是,经过数小时的测试后,我仍然无法得到该名称。


服务器的HierarchicalDataTemplate

<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上的几个相关帖子,例如How I can get content of TreeViewItem in WPF?WPF: Getting TreeViewItem's constituent controls,但我仍然无法正确使用。请帮助,谢谢。

1 个答案:

答案 0 :(得分:0)

我意识到我以前做的事情是完全错误的。 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 或其这对WPF初学者来说真的很有误导性。