I came up with a hack to get a folder browser in WPF, since Microsoft decided it was no worth adding it to WPF. No third party libraries are involved in this one.
I also found a work around to use it for MVVM situations.
To get the (hacked) folder browser, I employed the SaveFileDialog
I added the following imports
using System.IO;
using Microsoft.Win32;
Then I created a method to Get Folder Path
public string GetFolderPath()
{
SaveFileDialog folderDialog = new SaveFileDialog
{
AddExtension = false,
Title = "Select a Directory",
Filter = "All|*.*",
InitialDirectory = Environment.GetFolderPath(
Environment.SpecialFolder.MyDocuments),
CheckFileExists = false,
CheckPathExists = true,
FileName = Path.GetFileName("Select a folder"),
};
if (folderDialog.ShowDialog() != true)
{
return null;
}
string path = folderDialog.FileName;
path = Directory.GetParent(path).FullName;
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
return path;
}
It worked pretty well for my simple projects. But my newest project followed strict MVVM pattern so View, Model, and View Model were grouped into separate projects:
MyApp.View
MyApp.Core
MyApp.ViewModel
Each Core and ViewModel projects were both using the
.NET Standard
Library, which does not have the
Microsoft.Win32
library. So I had to find a way to get file browser and the (hacked) folder browser into the view model project.
In order to use the FileDialog
and the hacked FolderBroser
, I
Created an Interface in the Core project which was a shared library in both the View and ViewModel projects
public interface IDialogResults
{
string GetFilePath();
string GetFolderPath();
}
Then inherited it in the user control's partial class
public partial class FolderDialogUserControl : IDialogResults
which implemented the methods of the interface.
#region Implementation of IDialogResults
public string GetFilePath()
{
OpenFileDialog fileDialog = new OpenFileDialog()
{
AddExtension = true,
CheckFileExists = true,
CheckPathExists = true,
Filter = "All|*.*",
InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
};
if (!fileDialog.ShowDialog().HasValue)
{
return null;
}
return fileDialog.FileName;
}
public string GetFolderPath()
{
SaveFileDialog folderDialog = new SaveFileDialog
{
AddExtension = false,
Title = "Select a Directory",
Filter = "Database File|*.ldf;*.mdf",
InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
CheckFileExists = false,
CheckPathExists = true,
};
if (folderDialog.ShowDialog() != true)
{
return null;
}
string path = folderDialog.FileName;
path = Directory.GetParent(path).FullName;
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
return path;
}
#endregion
Then in the DialogUserControl.xaml
file I created the button to initiate the folder open command. In the button properties,I added the command binding to the ICommand Property from the DialogUserControlViewModel; then I added the DialogUserControl itself as CommandParameter
Command="{Binding OpenFolderDialog}"
CommandParameter="{Binding ElementName=DialogUserControl}"
Then in the DialogUser ViewModel, I added the following code
private void BrowseFolderDialog(object parameter)
{
BackupDestination = (parameter as IDialogResults)?.GetFolderPath();
}
private void BrowseFileDialog(object parameter)
{
RestoreSource = (parameter as IDialogResults)?.GetFilePath();
}
Aside normal folder browser feel tradeoff (which was hardly noticeable by users), everything worked fine.