2016-06-26 5 views

Antwort

0

Mit unten angefügten Eigenschaft Wenn jemals Baum Element ausgewählt ist oder die Auswahl geändert direkt den Befehl auf das Objekt wirft

public class ControlBehaviour 
{ 
    private static IDictionary<object, ICommand> dataContextCommandMap = new Dictionary<object, ICommand>(); 
    private static IDictionary<FrameworkElement, object> elementDataConextMap = new Dictionary<FrameworkElement, object>(); 
    /// <summary> 
    /// 
    /// </summary> 
    public static readonly DependencyProperty ControlEventProperty = 
     DependencyProperty.RegisterAttached("ControlEvent", typeof(RoutedEvent), typeof(ControlBehaviour), 
     new PropertyMetadata(OnTreeviewSelectionChanged)); 

    /// <summary> 
    /// 
    /// </summary> 
    /// <param name="target"></param> 
    /// <param name="value"></param> 
    public static void SetControlEvent(DependencyObject target, object value) 
    { 
     target.SetValue(ControlEventProperty, value); 
    } 
    /// <summary> 
    /// 
    /// </summary> 
    /// <param name="sender"></param> 
    /// <returns></returns> 
    public static RoutedEvent GetControlEvent(DependencyObject sender) 
    { 
     return sender.GetValue(ControlEventProperty) as RoutedEvent; 
    } 
    /// <summary> 
    /// Command to be executed 
    /// </summary> 
    public static readonly DependencyProperty CommandProperty = 
     DependencyProperty.RegisterAttached("Command", typeof(ICommand), 
     typeof(ControlBehaviour), new PropertyMetadata(CommandChanged)); 
    /// <summary> 
    /// Set ICommand to the dependency object 
    /// </summary> 
    /// <param name="target">dependency object</param> 
    /// <param name="value">I command</param> 
    public static void SetCommand(DependencyObject target, object value) 
    { 
     target.SetValue(CommandProperty, value); 
    } 
    /// <summary> 
    /// Get ICommand to the dependency object 
    /// </summary> 
    /// <param name="sender">dependency object</param> 
    /// <returns>ICommand of the dependency object</returns> 
    public static ICommand GetCommand(DependencyObject sender) 
    { 
     return sender.GetValue(CommandProperty) as ICommand; 
    } 
    /// <summary> 
    /// 
    /// </summary> 
    /// <param name="sender"></param> 
    /// <param name="e"></param> 
    static void OnTreeviewSelectionChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) 
    { 
     if (sender != null) 
     { 
      TreeView element = sender as TreeView; 
      if (element != null) 
      { 
       if (e.NewValue != null) 
       { 
        element.SelectedItemChanged += Handler; 
       } 
       if (e.OldValue != null) 
       { 
        element.SelectedItemChanged -= Handler; 
       } 
      } 
     } 
    } 
    /// <summary> 
    /// ICommand Changed 
    /// </summary> 
    /// <param name="sender">dependency object</param> 
    /// <param name="e">dependency args</param> 
    private static void CommandChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) 
    { 
     if (sender != null) 
     { 
      FrameworkElement cntrl = sender as FrameworkElement; 
      if (cntrl != null && cntrl.DataContext != null) 
      { 
       if (e.NewValue != null) 
       { 
        ICommand cmd = e.NewValue as ICommand; 
        if (cmd != null) 
        { 
         elementDataConextMap[cntrl] = cntrl.DataContext; 
         dataContextCommandMap[cntrl.DataContext] = cmd; 
        } 
       } 
       cntrl.Unloaded += FrameworkElementUnloaded; 
      } 
     } 
    } 
    /// <summary> 
    /// Framework element unload, Clears the removes the ICommand 
    /// </summary> 
    /// <param name="sender"></param> 
    /// <param name="e"></param> 
    private static void FrameworkElementUnloaded(object sender, RoutedEventArgs e) 
    { 
     FrameworkElement element = sender as FrameworkElement; 
     if (element != null && elementDataConextMap.ContainsKey(element)) 
     { 
      dataContextCommandMap.Remove(elementDataConextMap[element]); 
      elementDataConextMap.Remove(element); 
     } 
    } 
    /// <summary> 
    /// Routed Event Handler 
    /// </summary> 
    /// <param name="sender">sender</param> 
    /// <param name="e">EventArgs</param> 
    static void Handler(object sender, EventArgs e) 
    { 
     TreeView treeView = sender as TreeView; 
     if (treeView != null && treeView.SelectedItem != null && dataContextCommandMap.ContainsKey(treeView.SelectedItem) 
      && dataContextCommandMap[treeView.SelectedItem].CanExecute(treeView.SelectedItem)) 
     { 
      dataContextCommandMap[treeView.SelectedItem].Execute(treeView.SelectedItem); 
     } 
    } 
} 

Unten ist die xMAL die die oben angebaute Eigenschaft verwendet

<TreeView Grid.Row="1" Background="Transparent" ItemsSource="{Binding Directories}" Margin="0,10,0,0" Name="FolderListTreeView" 
       Height="Auto" HorizontalAlignment="Stretch" Width="300" local:ControlBehaviour.ControlEvent="TreeView.SelectedItemChanged" > 
       <TreeView.Resources> 
        <HierarchicalDataTemplate DataType="{x:Type local:FileSystem}" ItemsSource="{Binding SubDirectories}"> 
         <Label Content="{Binding Path= Name}" Name="NodeLabel" local:ControlBehaviour.Command="{Binding OnSelect}"/> 
        </HierarchicalDataTemplate> 
       </TreeView.Resources> 
      </TreeView> 

im Folgenden finden Sie Filesystem-Klasse, die in XAML gebunden ist

/// <summary> 
/// Implementation of file system class 
/// </summary> 

    public class FileSystem :BindableBase, IFileSystem, IEnumerable //BindableBase is base class which implemets INotifyPropertyChanged 
{ 
    #region Private members 
    private ObservableCollection<IFileSystem> subDirectoriesField; 
    private ObservableCollection<IFileSystem> filesField; 
    #endregion 

    #region Public properties 
    /// <summary> 
    /// Gets and sets all the Files in the current folder 
    /// </summary> 
    public ObservableCollection<IFileSystem> SubDirectories 
    { 
     get 
     { 
      return subDirectoriesField; 
     } 
     set 
     { 
      if (subDirectoriesField != value) 
      { 
       subDirectoriesField = value; 
       NotifyPropertyChanged("SubDirectories"); 
      } 
     } 
    } 
    /// <summary> 
    /// Gets and sets all the files in the current folder 
    /// </summary> 
    public ObservableCollection<IFileSystem> Files 
    { 
     get 
     { 
      return filesField; 
     } 
     set 
     { 
      if (filesField != value) 
      { 
       filesField = value; 
       RaisePropertyChanged("Files"); 
      } 
     } 
    } 
    /// <summary> 
    /// Gets or sets the type of the file 
    /// </summary> 
    public FileSystemType FileType 
    { 
     get; 
     set; 
    } 
    /// <summary> 
    /// Gets or sets the size of the file 
    /// </summary> 
    public long Size 
    { 
     get; 
     set; 
    } 
    /// <summary> 
    /// Gets or sets name of the file system 
    /// </summary> 
    public string Name 
    { 
     get; 
     set; 
    } 
    /// <summary> 
    /// Gets or sets full path of the file system 
    /// </summary> 
    public string FullPath 
    { 
     get; 
     set; 
    } 
    /// <summary> 
    /// object of parent, null if the current node is root 
    /// </summary> 
    public FileSystem Parent 
    { 
     get; 
     set; 
    } 
    /// <summary> 
    /// Returns ICommand 
    /// </summary> 
    public ICommand OnSelect 
    { 
     get 
     { 
      return new Command_R(Execute);//Command_R is implemention of your ICommand 
     } 
    } 
    #endregion 

    #region Constructor 
    /// <summary> 
    /// Constructor 
    /// </summary> 
    /// <param name="path">path of the folder</param> 
    /// <param name="parent">object of the parent</param> 
    public FileSystem(string fullPath, FileSystem parent, FileSystemType 
     type = FileSystemType.Directory) 
    { 
     Name = fullPath != null ? GetNameFileName(fullPath) : fullPath; 
     FullPath = fullPath; 
     Parent = parent; 
     FileType = type; 
     FilesAndSubDirectoriesDetails(fullPath); 
    } 

    #endregion 

    #region Public methods 
    /// <summary> 
    /// Updates the file size if there is a change 
    /// </summary> 
    /// <param name="deleteFilzeSize"></param> 
    public void UpdateFileSize(long deleteFilzeSize) 
    { 
     UpdatePredecessor(this, deleteFilzeSize); 
    } 
    /// <summary> 
    /// Gets the enumeration list 
    /// </summary> 
    /// <returns>returns the enumeration list</returns> 
    public IEnumerator GetEnumerator() 
    { 
     return SubDirectories.GetEnumerator(); 
    } 
    #endregion 

    #region Private methods 
    /// <summary> 
    /// Finds the details of the files and sub directories 
    /// </summary> 
    /// <param name="fullPath"></param> 
    private void FilesAndSubDirectoriesDetails(string fullPath) 
    { 
     if (FileType.Equals(FileSystemType.Directory)) 
     { 
      AddFilesAndSubDirectories(fullPath); 
      CalculateDirectorySize(); 
     } 
     else 
     { 
      //Write code to calcuate the File Size 
      //Size = FileInfo.GetSize(fullPath); 
     } 

    } 
    /// <summary> 
    /// Finds and adds the files and sub directories 
    /// </summary> 
    /// <param name="fullPath"></param> 
    private void AddFilesAndSubDirectories(string fullPath) 
    { 

     string[] subDirectories = Directory.GetDirectories(fullPath); 
     SubDirectories = new ObservableCollection<IFileSystem>(); 
     foreach (string directory in subDirectories) 
     { 
      SubDirectories.Add(new FileSystem(directory, this)); 
     } 
     Files = new ObservableCollection<IFileSystem>(); 
     string[] files = File.GetFiles(fullPath); 
     foreach (string fileName in files) 
     { 
      Files.Add(new FileSystem(fileName, this, FileSystemType.File)); 
     } 

    } 
    /// <summary> 
    /// Calculates the current directory size 
    /// </summary> 
    private void CalculateDirectorySize() 
    { 
     foreach (FileSystem directory in SubDirectories) 
     { 
      Size += directory.Size; 
     } 
     foreach (FileSystem file in Files) 
     { 
      Size += file.Size; 
     } 

    } 
    /// <summary> 
    /// Updates the file size of the predecessors 
    /// </summary> 
    /// <param name="currentNode">current node</param> 
    /// <param name="deleteFilzeSize">file to be updated</param> 
    private void UpdatePredecessor(FileSystem currentNode, long deletedFilzeSize) 
    { 
     if (currentNode != null) 
     { 
      currentNode.Size -= deletedFilzeSize; 
      UpdatePredecessor(currentNode.Parent, deletedFilzeSize); 
     } 
    } 
    /// <summary> 
    /// Executes ICommand 
    /// </summary> 
    /// <param name="parameter">parameter</param> 
    private void Execute(object parameter) 
    { 
     //Do your Job 
     MessageBox.Show(FullPath); 
    } 
    #endregion 
} 

Und die Schnittstelle für die Klasse

/// <summary> 
/// Type of the file 
/// </summary> 
public enum FileSystemType 
{ 
    /// <summary> 
    /// File 
    /// </summary> 
    File, 
    /// <summary> 
    /// Directory 
    /// </summary> 
    Directory 
} 
/// <summary> 
/// Interface for File system 
/// </summary> 
public interface IFileSystem 
{ 
    /// <summary> 
    /// Gets or sets file type 
    /// </summary> 
    FileSystemType FileType 
    { 
     get; 
     set; 
    } 
    /// <summary> 
    /// Gets or sets the file size 
    /// </summary> 
    long Size 
    { 
     get; 
     set; 
    } 
    /// <summary> 
    /// Gets or sets name of the file system 
    /// </summary> 
    string Name 
    { 
     get; 
     set; 
    } 
    /// <summary> 
    /// Gets or sets full path of the file system 
    /// </summary> 
    string FullPath 
    { 
     get; 
     set; 
    } 
}