2012-04-02 64 views
0

我正在开发一个简单的WPF资源管理器树。 Sacha Barber写了一篇关于它的好文章http://www.codeproject.com/Articles/21248/A-Simple-WPF-Explorer-Tree,我喜欢这种方法,我正在使用它。一个简单的WPF资源管理器树

有一件事我不能做。我也想显示文件,而不仅仅是目录。但我不明白如何识别它是文件还是文件夹。

下面是完整的代码

public partial class Window1 : Window 
    { 
     private object dummyNode = null; 

     public Window1() 
     { 
      InitializeComponent(); 
     } 

     public string SelectedImagePath { get; set; } 

     private void Window_Loaded(object sender, RoutedEventArgs e) 
     { 
      foreach (string s in Directory.GetLogicalDrives()) 
      { 
       TreeViewItem item = new TreeViewItem(); 
       item.Header = s; 
       item.Tag = s; 
       item.FontWeight = FontWeights.Normal; 
       item.Items.Add(dummyNode); 
       item.Expanded += new RoutedEventHandler(folder_Expanded); 
       foldersItem.Items.Add(item); 
      } 
     } 

     void folder_Expanded(object sender, RoutedEventArgs e) 
     { 
      TreeViewItem item = (TreeViewItem)sender; 
      if (item.Items.Count == 1 && item.Items[0] == dummyNode) 
      { 
       item.Items.Clear(); 
       try 
       { 
        foreach (string s in Directory.GetDirectories(item.Tag.ToString())) 
        { 
         TreeViewItem subitem = new TreeViewItem(); 
         subitem.Header = s.Substring(s.LastIndexOf("\\") + 1); 
         subitem.Tag = s; 
         subitem.FontWeight = FontWeights.Normal; 
         subitem.Items.Add(dummyNode); 
         subitem.Expanded += new RoutedEventHandler(folder_Expanded); 
         item.Items.Add(subitem); 
        } 
        // this code I added to show the files 
        foreach (string f in Directory.GetFiles(item.Tag.ToString())) 
        { 
         TreeViewItem subitem = new TreeViewItem(); 
         subitem.Header = f.Substring(f.LastIndexOf("\\") + 1); 
         subitem.Tag = f; 
         subitem.FontWeight = FontWeights.Normal; 
         subitem.Items.Add(dummyNode); 
         item.Items.Add(subitem); 
        } 
       } 
       catch (Exception) { } 
      } 
     } 

     private void foldersItem_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e) 
     { 
      TreeView tree = (TreeView)sender; 
      TreeViewItem temp = ((TreeViewItem)tree.SelectedItem); 

      if (temp == null) 
       return; 
      SelectedImagePath = ""; 
      string temp1 = ""; 
      string temp2 = ""; 
      while (true) 
      { 
       temp1 = temp.Header.ToString(); 
       if (temp1.Contains(@"\")) 
       { 
        temp2 = ""; 
       } 
       SelectedImagePath = temp1 + temp2 + SelectedImagePath; 
       if (temp.Parent.GetType().Equals(typeof(TreeView))) 
       { 
        break; 
       } 
       temp = ((TreeViewItem)temp.Parent); 
       temp2 = @"\"; 
      } 
      //show user selected path 
      // MessageBox.Show(SelectedImagePath); 
     } 

    } 

窗口

<Window x:Class="WPF_Explorer_Tree.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:WPF_Explorer_Tree" 
    Title="Window1" Height="300" Width="300" Loaded="Window_Loaded"> 
    <Grid> 
     <TreeView x:Name="foldersItem" SelectedItemChanged="foldersItem_SelectedItemChanged" Width="Auto" Background="#FFFFFFFF" BorderBrush="#FFFFFFFF" Foreground="#FFFFFFFF"> 
      <TreeView.Resources> 
       <Style TargetType="{x:Type TreeViewItem}"> 
        <Setter Property="HeaderTemplate"> 
         <Setter.Value> 
          <DataTemplate> 
           <StackPanel Orientation="Horizontal"> 
           <Image Name="img" Width="20" Height="20" Stretch="Fill" 
             Source="{Binding 
             RelativeSource={RelativeSource 
             Mode=FindAncestor, 
             AncestorType={x:Type TreeViewItem}}, 
             Path=Header, 
             Converter={x:Static local:HeaderToImageConverter.Instance}}"  
             /> 
            <TextBlock Text="{Binding}" Margin="5,0" /> 
           </StackPanel> 
          </DataTemplate> 
         </Setter.Value> 
        </Setter> 
       </Style> 
      </TreeView.Resources> 
     </TreeView> 
    </Grid> 
</Window> 

转换器

[ValueConversion(typeof(string), typeof(bool))] 
    public class HeaderToImageConverter : IValueConverter 
    { 
     public static HeaderToImageConverter Instance = new HeaderToImageConverter(); 

     public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      // this is a diskdrive 
      if ((value as string).Contains(@"\")) 
      { 
       Uri uri = new Uri("pack://application:,,,/Images/diskdrive.png"); 
       BitmapImage source = new BitmapImage(uri); 
       return source; 
      } 
      else 
      { 
       //maybe this is a directory or maybe this is a file. How do I know it? 
       Uri uri = new Uri("pack://application:,,,/Images/folder.png"); 
       //Uri uri = new Uri("pack://application:,,,/Images/file.png"); 
       BitmapImage source = new BitmapImage(uri); 
       return source; 
      } 
     } 

     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      throw new NotSupportedException("Cannot convert back"); 
     } 
    } 

我怎么知道里面HeaderToImageConverter.Convert如果当前值是一个目录的名称或文件的名称?

回答

1

一个据我了解你的代码是自己的上下文树视图项,TreeViewItem的Tag属性包含绝对路径。你可以绑定到Tag属性,而不是Header,并在您检查转换器这样的:

string path = value as string; 
if (File.Exists(path)) 
{ 
    ... 
} 
else if (Directory.Exists(path)) 
{ 
    ... 
} 

又见here

0

首先,您的代码并不完美,我强烈建议您使用分层数据模板和视图模型,它将解决此问题以及将来的许多问题。

但是,如果你想要一个快速和肮脏的解决方案,你可以尝试两件事: 1.文件的标题字符串将有文件扩展名。 2.你可以注入你通过数据上下文属性