Простое дерево обозревателя WPF - PullRequest
0 голосов
/ 02 апреля 2012

Я разрабатываю простое дерево обозревателя WPF.Саша Барбер написал хорошую статью об этом http://www.codeproject.com/Articles/21248/A-Simple-WPF-Explorer-Tree, Мне нравится этот подход, и я использую его.

Есть вещь, которую я не могу сделать.Я хотел бы показать файлы, а не только каталоги.Но я не понимаю, как мне распознать, является ли это файл или папка.

Вот полный код

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, является ли текущее значение именем каталога или именем файла?

Ответы [ 2 ]

0 голосов
/ 02 апреля 2012

Насколько я понял ваш код, свойство Tag TreeViewItem содержит абсолютный путь. Вы можете привязать к свойству Tag вместо Header, и в вашем конвертере проверьте это так:

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

См. Также здесь .

0 голосов
/ 02 апреля 2012

Во-первых, ваш код не идеален, я настоятельно рекомендую вам работать с шаблоном иерархических данных и просматривать модели, это решит эту проблему и многое другое, что у вас будет в будущем.

Но если выЕсли вы хотите быстрое и грязное решение, вы можете попробовать 2 вещи: 1. Строка заголовка файла будет иметь расширение файла.2. Вы можете внедрить свой собственный контекст в элемент дерева просмотра через свойство Data Context

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...