Feedback

C# - FolderBrowseDialog in WPF

Veröffentlicht von am 2/24/2010
(1 Bewertungen)
WPF hat leider keinen FolderBrowseDialog mehr wie in WinForms. Daher habe ich angefangen diesen nach zubauen. Ich habe jetzt die Version 0.1.0 veröffentlicht (http://wpfdialogs.codeplex.com/), wo der FolderBrowseDialog ein DialogResult hat (wie in WinForms nicht wie WPF-Dialoge) und die Möglichkeit besteht den ausgewählten Pfad auszulesen. Also einfach die Grundfunktionen bereitstellt

IDialog.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WPF_Dialogs
{
/// <summary>
/// This Interface implements general Dialogfeatures: enum with Dialogresults
/// </summary>
public interface IDialog
{
EDialogResult DialogResult { get; set; }
}

/// <summary>
/// Represents all possible DialogResults (same as in the System.Windows.Forms-namespace)
/// </summary>
public enum EDialogResult : int
{
Abort = 1,
Cancel = 2,
Ignore = 3,
No = 4,
None = 5,
OK = 6,
Retry = 7,
Yes = 8
}
}


Custom Controls\DialogButton.xaml

< Button x:Class="WPF_Dialogs.Custom_Controls.DialogButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d" Height="23" Width="75">

< /Button>


Custom Controls\DialogButton.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

using WPF_Dialogs;

namespace WPF_Dialogs.Custom_Controls
{
/// <summary>
/// Interaction logic for DialogButton.xaml
/// </summary>
public partial class DialogButton : Button, IDialog
{
/// <summary>
/// Gets or sets the dialog result. DEFAULT: None
/// </summary>
/// <value>The dialog result.</value>
public EDialogResult DialogResult { get; set; }

public WPF_Dialogs.Dialogs.FolderBrowseDialog FolderBrowseDialog
{
get
{
throw new System.NotImplementedException();
}
set
{
}
}

public DialogButton()
{
InitializeComponent();
this.Content = "DialogButton";
this.DialogResult = EDialogResult.None;
this.Height = 23;
this.Width = 75;
}
}
}


FolderBrowseDialog.xaml XAML-Code für das Code-Snippet

< Window x:Class="WPF_Dialogs.Dialogs.FolderBrowseDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:custom="clr-namespace:WPF_Dialogs.Custom_Controls"
Title="Open Folder" Height="300" Width="300" ResizeMode="NoResize">
< Grid>
< custom:DialogButton Margin="102,226,102,12" Content="OK" DialogResult="OK" Click="DialogButton_clicked" />
< custom:DialogButton Margin="181,226,22,12" Content="Cancel" DialogResult="Cancel" Click="DialogButton_clicked" />
< Canvas Height="208" HorizontalAlignment="Left" Margin="12,12,0,0" Name="canvas1" VerticalAlignment="Top" Width="254">
< TreeView Canvas.Left="0" Canvas.Top="0" Height="208" Name="treeViewFolders" Width="254" />
< /Canvas>
< /Grid>
< /Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.IO;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

using WPF_Dialogs; // Dadurch kann direkt auf IDialog und EDialogResult zugegriffen werden
using WPF_Dialogs.Custom_Controls; //Beinhaltet bisher nur den DialogButton

namespace WPF_Dialogs.Dialogs
{
    public partial class FolderBrowseDialog : Window, IDialog
    {
        public new EDialogResult DialogResult { set; get; }
        public string SelectedPath { get; private set; }

        public FolderBrowseDialog()
        {
            InitializeComponent();
            loadFolders();
        }

        private void DialogButton_clicked(object sender, RoutedEventArgs e)
        {
            DialogButton o = (DialogButton)sender;
            this.DialogResult = o.DialogResult;
            if (this.DialogResult == EDialogResult.OK && this.treeViewFolders.SelectedItem != null)
                this.SelectedPath = ((TreeViewItem)this.treeViewFolders.SelectedItem).ToolTip.ToString();
            this.Close();
        }

        /// <summary>
        /// Zeigt den Dialog an. Kann auch so verwendet werden als ob es keinen Rückgabetyp hätte
        /// </summary>
        /// <returns></returns>
        public EDialogResult showDialog()
        {
            this.ShowDialog();
            return this.DialogResult;
        }

        private void loadFolders() //Laden der Ordner beim initialisieren
        {
            string desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); //Liest den Pfad zum Desktop
            treeViewFolders.Items.Add(loadDirectories(desktop));
            ((TreeViewItem)treeViewFolders.Items[0]).IsExpanded = true;
        }

        private TreeViewItem loadDirectories(string path) //lädt alle Dateien vom path (nur dekstop) aus
        {
            TreeViewItem tvi = new TreeViewItem();
            string[] folders = Directory.GetLogicalDrives();
            tvi.Header = path.Remove(0, path.LastIndexOf("\\") + 1);
            tvi.ToolTip = path;
            tvi.Items.Add(createTreeVieItem(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)));
            for (int i = 0; i < folders.Length; i++) //Ausgeben der verfügbaren laufwerk(e/sbuchstaben)
            {
                try
                {
                    tvi.Items.Add(createTreeVieItem(folders[i]));
                    tvi.Expanded += new RoutedEventHandler(tvi_Expanded);
                }
                catch (Exception e) //The Drive is not ready, bad solution but best now
                { }
            }
            folders = Directory.GetDirectories(path);
            for (int i = 0; i < folders.Length; i++) //ausgeben der Ordner
            {
                tvi.Items.Add(createTreeVieItem(folders[i]));
                tvi.Expanded +=new RoutedEventHandler(tvi_Expanded);
            }

            return tvi;
        }

        private TreeViewItem createTreeVieItem(string path) //hilfsfunktion zum erstellen der treeviewitems
        {
            TreeViewItem tvi = new TreeViewItem();
            string header = path.Remove(0, path.LastIndexOf("\\") + 1);
            if (header == "") //The Path is a Drive (e.g. C\, after removing \ -> "")
            {
                header = path.Remove(path.Length - 1);
            }
            tvi.Header = header;
            tvi.ToolTip = path;
            if (path != "")
            {
                if (Directory.GetDirectories(path).Length > 0)
                    tvi.Items.Add(new TreeViewItem());
            }
            return tvi;
        }

        private void tvi_Expanded(object sender, RoutedEventArgs e) //nachladen der unterordner beim expandieren
        {
            var tvi = e.OriginalSource as TreeViewItem;
            if (tvi.Items.Count <= 1 && tvi.IsExpanded)
            {
                tvi.Items.Clear();
                string[] folders = Directory.GetDirectories(tvi.ToolTip.ToString());
                for (int i = 0; i < folders.Length; i++)
                {
                    try
                    {
                        tvi.Items.Add(createTreeVieItem(folders[i]));
                        tvi.Expanded += new RoutedEventHandler(tvi_Expanded);
                    }
                    catch (Exception ex) //If there are no rights for the folder, bad solution but best now
                    { }
                }
            }
        }
    }
}
Abgelegt unter Dialog, WPF, FolderBrowseDialog.

3 Kommentare zum Snippet

TKundNobody2 schrieb am 2/24/2010:
Ich weiß, dass es bei diesem Snippet noch Verbesserungsmöglichkeiten gibt, aber für den Anfang sollte es reichen. Ich finde sogar das die Performance besser ist als dem aus WinForms, oder kommt mir das nur so vor?
TKundNobody2 schrieb am 2/24/2010:
Version 0.1.1 habe ich auf http://wpfdialogs.codeplex.com/ veröffentlicht.
Das bringt unter anderem folgende Verbesserungen:
* Code Optimierung
* Akzeptiert ein Start-Pfad
* Gibt eine Exception zurück wenn der InitialPath nicht existiert (falschen Pfad übergeben)
* Das Verwenden von Window.ShowDialog() ist nicht mehr möglich
TKundNobody2 schrieb am 3/2/2010:
Version 0.1.2 auf http://wpfdialogs.codeplex.com/
bringt unter anderem folgende Verbesserungen:
* Nun wird der Computer angezeigt, statt nur die Laufwerke
* Es kann ein Pfad übergeben werden (SelectedPath), der am Anfang ausgewählt ist
* Die Beschriftungen der Buttons kann über die jeweilige Eigenschaft im FileBrowseDialog angepasst werden
 

Logge dich ein, um hier zu kommentieren!