2010-12-03 11 views
1

私は、Heirarchical DataTemplatesとTreeViewsをWPFで頭に入れようとしていますが、何か問題があります。WPF Heirachical DataTemplate in TreeView

私は以下のようにフォーム上にTreeViewだけのアプリケーションを作成し、DirectoryオブジェクトとFileオブジェクトの両方に対してHierarchicalDataTemplateを定義しました。次に、私のモデルのDirectoriesプロパティ(ObservableCollection)にTreeViewをバインドします。

<Grid> 
     <Grid.Resources> 

      <HierarchicalDataTemplate DataType="{x:Type local:Directory}" ItemsSource ="{Binding Directories}"> 
       <TextBlock Text="{Binding Path=Name}"/> 
      </HierarchicalDataTemplate> 
      <HierarchicalDataTemplate DataType="{x:Type local:File}" ItemsSource ="{Binding Files}"> 
       <TextBlock Text="{Binding Path=FileName}"/> 
      </HierarchicalDataTemplate> 
     </Grid.Resources> 
     <TreeView Margin="12,12,0,12" Name="treeView1" HorizontalAlignment="Left" Width="204" > 
      <TreeViewItem ItemsSource="{Binding Directories}" Header="Folder Structure" /> 
     </TreeView> 
    </Grid> 

これは私が私のディレクトリが表示ツリービューでその中で動作し、それが再帰的にすべてのサブディレクトリを表示しますが、私が見てみたいことはディレクトリとファイルです!モデルをチェックしたところ、サブディレクトリのいくつかにはファイルがありますが、ツリーには表示されません。

私はそれはそう問題や私のモデルである私のテンプレートであれば、私はそれらのすべてが含まれているかわかりません! :-)

おかげ

ワンショット

public partial class MainWindow : Window 
{ 

    public MainWindow() 
    { 
     InitializeComponent(); 

    } 


    private MainWindowViewModel _vm; 

    public MainWindowViewModel VM 
    { 
     set 
     { 
      _vm = value; 
      this.DataContext = _vm; 
     } 
    } 

    private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
     var d = new Directory() { Name = "temp" }; 
     recurseDir("c:\\temp", ref d); 

     VM = new MainWindowViewModel(new List<Directory>() { d });    
    } 

    private void recurseDir(string path, ref Directory dir) 
    { 
     var files = System.IO.Directory.GetFiles(path); 
     var dirs = System.IO.Directory.GetDirectories(path); 

     dir.Name = path.Substring(path.LastIndexOf("\\")+1); 

     for (int i = 0; i < files.Length; i++) 
     { 
      var fi = new FileInfo(files[i]); 
      dir.Files.Add(new File() { 
       FileName = System.IO.Path.GetFileName(files[i]), 
       DirectoryPath = System.IO.Path.GetDirectoryName(files[i]), 
       Size = fi.Length, 
       Extension= System.IO.Path.GetExtension(files[i]) 
      }); 

     } 

     for (int i = 0; i < dirs.Length; i++) 
     { 
      var d = new Directory() { Name = dirs[i].Substring(dirs[i].LastIndexOf("\\")+1) }; 
      recurseDir(dirs[i], ref d); 
      dir.Directories.Add(d); 

     } 

    } 
} 

-

public class MainWindowViewModel 
     : DependencyObject 
    { 


     public MainWindowViewModel(List<Directory> Dirs) 
     { 
      this.Directories = new ObservableCollection<Directory>(Dirs); 
     } 

     public ObservableCollection<Directory> Directories 
     { 
      get { return (ObservableCollection<Directory>)GetValue(DirectoriesProperty); } 
      set { SetValue(DirectoriesProperty, value); } 
     } 

     public static readonly DependencyProperty DirectoriesProperty = 
      DependencyProperty.Register("Directories", typeof(ObservableCollection<Directory>), typeof(MainWindowViewModel), new UIPropertyMetadata(null)); 

     public Directory BaseDir 
     { 
      get { return (Directory)GetValue(BaseDirProperty); } 
      set { SetValue(BaseDirProperty, value); } 
     } 

     public static readonly DependencyProperty BaseDirProperty = 
      DependencyProperty.Register("BaseDir", typeof(Directory), typeof(MainWindowViewModel), new UIPropertyMetadata(null)); 


    } 

-

public class Directory 
    { 
     public Directory() 
     { 
      Files = new List<File>(); 
      Directories = new List<Directory>(); 
     } 
     public List<File> Files { get; private set; } 
     public List<Directory> Directories { get; private set; } 
     public string Name { get; set; } 
     public int FileCount 
     { 
      get 
      { 
       return Files.Count; 
      } 
     } 
     public int DirectoryCount 
     { 
      get 
      { 
       return Directories.Count; 
      } 
     } 
     public override string ToString() 
     { 
      return Name; 
     } 
    } 

-

public class File 
    { 
     public string DirectoryPath { get; set; } 
     public string FileName { get; set; } 
     public string Extension { get; set; } 
     public double Size { get; set; } 
     public string FullPath 
     { 
      get 
      { 
       return System.IO.Path.Combine(DirectoryPath, FileName); 
      } 
     } 
     public override string ToString() 
     { 
      return FileName; 
     } 
    } 

答えて

2

再びこれを見てください:

 <HierarchicalDataTemplate DataType="{x:Type local:Directory}" ItemsSource ="{Binding Directories}"> 
      <TextBlock Text="{Binding Path=Name}"/> 
     </HierarchicalDataTemplate> 
     <HierarchicalDataTemplate DataType="{x:Type local:File}" ItemsSource ="{Binding Files}"> 
      <TextBlock Text="{Binding Path=FileName}"/> 
     </HierarchicalDataTemplate> 

何を言っていることは、あなたがタイプFileのオブジェクトに遭遇した場合、テキストブロックでそれを表示することで、下のプロパティFilesからその子を取得File

public class Directory 
{ 
    //... 
    public IEnumerable<Object> Members 
    { 
     get 
     { 
      foreach (var directory in Directories) 
       yield return directory; 

      foreach (var file in Files) 
       yield return file; 
     } 
    } 
    //... 
} 

、その後、あなたのテンプレートは次のようになります:あなたが本当にしたいことは、あなたがディレクトリとファイルの両方を公開する新しいプロパティを作成する必要がありますので、ファイルは、各ディレクトリの下に表示するためのものです

<HierarchicalDataTemplate DataType="{x:Type local:Directory}" ItemsSource ="{Binding Members}"> 
     <TextBlock Text="{Binding Path=Name}"/> 
    </HierarchicalDataTemplate> 
    <DataTemplate DataType="{x:Type local:File}"> 
     <TextBlock Text="{Binding Path=FileName}"/> 
    </DataTemplate> 

更新日:

実際には、メンバーのコレクション変更通知を受信したい場合は、上記の方法では不十分です。そうであれば、新しいObservableCollectionを作成し、それにディレクトリとファイルエントリを追加して、ファイルコレクションとディレクトリコレクションに追加することをお勧めします。

代わりに、あなたはあなたの情報を保存し、単一のコレクションにすべてをかける方法を再検討することをお勧めします。他のリストは、メインコレクションの単にフィルタリングされたビューです。

+0

乾杯ダンは、私は、ディレクトリとファイルの両方が今継承し、それを使用する基本型の二次監視可能なコレクションを取り込むのご提案を行ってきました! – OneSHOT