我不是WPF的专家,所以请原谅我,如果我的问题很奇怪。如果有什么不合理的话,我会非常乐意详述。
我有一个树视图,它绑定了一个类的可观察集合。当我的程序启动时,我会读取特定目的地的每个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的对象以访问filepath属性。这有可能吗?
答案 0 :(得分:6)
可以通过解析TreeViewItem的DataContext:
FileItem fileItem = (treeViewItem.DataContext as FileItem);
更优雅的方法是在FileItem类中使用MouseInput Bindings和Command。
在您的Datatemplate for 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;}
}
P.S。:如果您不熟悉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();
}
}
}
命令对于这样的szenarios更有效。你不需要走视觉树,你根本不需要代码。
答案 1 :(得分:0)
检查DataContext
的{{1}}属性并尝试将其转换为TreeViewItem
类型。
此外,您可以将FileItem的模板定义为简单FileItem
,而不是DataTemplate
。