4

我不是 WPF 方面的专家,所以如果我的问题措辞奇怪,请原谅我。如果有什么不合理的地方,我会非常乐意详细说明。

我有一个绑定类的 observablecollection 的树视图。当我的程序启动时,我读取特定目的地的每个 C 源代码文件,将其名称和文件路径存储在提到的类中。

在此处输入图像描述

这是我的 XAML:

<TreeView Name="ProgramTree" ItemsSource="{Binding ProgramItemCollection}" 
                                      cal:Message.Attach="[Event PreviewMouseRightButtonDown] = [Action TestRight($dataContext,$eventArgs)];
                                      [Event PreviewMouseDoubleClick] = [Action NodeDoubleClick($dataContext,$eventArgs)]">

    <TreeView.Resources>
        <!--DataTemplate for Program Nodes (Top) and binds FileItemNodes-->
        <HierarchicalDataTemplate DataType="{x:Type my:ProgramItem}"
                                        ItemsSource="{Binding FileItemCollection}">
            <Border Width="100" BorderBrush="RoyalBlue" 
                                            Background="RoyalBlue"  BorderThickness="1" 
                                            CornerRadius="2" Margin="2" Padding="2" >
                <StackPanel Orientation="Horizontal">
                    <Image Style="{StaticResource IconStyle}" Margin="2" Source="{StaticResource FolderIcon}" />
                    <TextBlock Margin="2" Text="{Binding ProgramName}"
                                                           Foreground="White" FontWeight="Bold"/>
                </StackPanel>
            </Border>
        </HierarchicalDataTemplate>
        <!--DataTemplate for File Nodes (Subnodes of Program Nodes)-->
        <HierarchicalDataTemplate DataType="{x:Type my:FileItem}">
            <Border Width="80"  Background="LightBlue" CornerRadius="2" Margin="1" >
                <StackPanel Orientation="Horizontal">
                    <Image Margin="2" />
                    <TextBlock Margin="2" Text="{Binding NodeName}" />
                </StackPanel>
            </Border>
        </HierarchicalDataTemplate>
    </TreeView.Resources>

代码隐藏:

public class FileItem
{
    public string NodeName { get; set; }
    public string FullName { get; set; }
    public string Extension { get; set; }
}

public class ProgramItem : PropertyChangedBase
{
    private ObservableCollection<FileItem> fileItemCollection;
    ...

我现在要做的是在节点上挂钩双击事件并打开相关文件。

    public void NodeDoubleClick(object sender, MouseButtonEventArgs e)
    {
        TreeViewItem treeViewItem = VisualUpwardSearch(e.OriginalSource as DependencyObject);

        if (treeViewItem != null)
        {
            //Open file
        }
    }

    private static TreeViewItem VisualUpwardSearch(DependencyObject source)
    {
        while (source != null && !(source is TreeViewItem))
            source = VisualTreeHelper.GetParent(source);

        return source as TreeViewItem;
    }

我可以毫无问题地检索双击的节点(treeviewitem)。问题是我想从我双击访问文件路径属性的节点中检索 FileItem 的对象。这可能吗?

4

2 回答 2

8

可以通过解析 TreeViewItem 的 DataContext:

FileItem fileItem = (treeViewItem.DataContext as FileItem);

更优雅的方法是在 FileItem 类中使用 MouseInput 绑定和命令。

在 FileItem 的数据模板中:

<StackPanel Orientation="Horizontal">
    <StackPanel.InputBindings>
        <MouseBinding MouseAction="LeftDoubleClick" 
                      Command="{Binding OpenFileCommand}" />
    </StackPanel.InputBindings>
    <Image Margin="2" />
    <TextBlock Margin="2" Text="{Binding NodeName}" />
</StackPanel>

在您的 FileItem 中:

public class FileItem
{
   public FileItem()
   {
       this.OpenFileCommand 
           = new SimpleCommand(()=> Process.StartNew(this.FullName));
   }

   public string NodeName { get; set; }
   public string FullName { get; set; }
   public string Extension { get; set; }
   public ICommand OpenFileCommand { get; set;}
}

PS:如果你不习惯 WPF 的命令,一个简单的 ICommand 的基本实现可能是:

public class SimpleCommand : System.Windows.Input.ICommand
{
    public SimpleCommand(Action action)
    {
        this.Action = action;
    }

    public Action Action { get; set; }

    public bool CanExecute(object parameter)
    {
        return (this.Action != null);
    }

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
        if (this.Action != null)
        {
            this.Action();
        }
    }
}

对于这种情况,命令要有效得多。你不需要走可视化树,你根本不需要代码。

于 2012-09-20T12:29:06.103 回答
1

检查的DataContext属性TreeViewItem并尝试将其转换为FileItem类型。

您也可以将 FileItem 的模板定义为 simple DataTemplate,而不是HierarchicalDataTemplate.

于 2012-09-20T12:23:59.237 回答