2012-09-20 38 views
3

我不是WPF的專家,所以請原諒我,如果我用古怪的詞語來表達我的問題。如果沒有任何意義,我會很樂意闡述。從TreeView檢索節點上的綁定對象

我有一個treeview綁定一個類的observablecollection。當我的程序啓動時,我讀取了特定目的地的每個C源代碼文件,將其名稱和文件路徑存儲在所提及的類中。

enter image description here

這是我的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屬性。這可能嗎?

回答

6

這是解決樹型視圖的DataContext的可能:

FileItem fileItem = (treeViewItem.DataContext as FileItem); 

更優雅的方式是使用MouseInput綁定和命令在你的FileItem類。

在你的DataTemplate爲的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(); 
     } 
    } 
} 

命令對於這樣的szenarios更加有效。你不需要走視覺樹,你根本不需要代碼。

+0

壯觀的答案,甚至給了我一個更好的解決方案來解決這個問題!非常感謝。 – l46kok

+0

謝謝。 WPF非常強大,但難點在於找到所有這些最佳實踐。如果你對WPF感興趣,我建議你看看棱鏡模式:[棱鏡](http://msdn.microsoft.com/en-us/library/gg406140.aspx),尤其是第5章和第6章 – JanW

+0

@JanW :我有一個關於'ICommand.Execute(...)'的問題:傳遞給'parameter'對象的是什麼? – IAbstract

0

檢查DataContext屬性TreeViewItem並嘗試將其轉換爲FileItem類型。

您也可以將FileItem的模板定義爲簡單的DataTemplate而不是HierarchicalDataTemplate