Здравствуйте, я использую System.Windows.Forms.FolderBrowserDialog
в своем WPF application
для выбора папок на компьютере пользователя. Выбранная папка отображается в TextBox
и также проверяется в модели представления.FolderBrowserDialog в приложении WPF, исключающем исключение приложения вместо исключения привязки
Я пытаюсь отобразить недействительную папку, Error Template
сообщения ниже TextBox
для следующего сценария:
- Если папка не существует, и не доступна.
- если пользователь выбирает папку, являющуюся системной папкой. В этом примере я жестко закодировал значение как
@"c:\windows\boot"
.
Что я замечаю: если я нахожу папку, которая не существует, я получу исключение связывания, которое позволяет мне установить шаблон ошибки.
Но если я выбираю диск, к которому у пользователя нет доступа, или я выбираю @"c:\windows\boot"
, я получу исключение, которое либо попадает в исключение unhandle App.xaml
, либо если у вас есть попытка catch (где установлена папка) он будет пойман там. Как я могу получить это как обязательное исключение? Прежде чем я решила оставить это как попытку поймать, я хотел бы понять, есть ли в любом случае я могу иметь это как обязательное исключение (которое сохраняет щелчок!).
Вот код:
public class MainWindowViewModel : INotifyPropertyChanged
{
public MainWindowViewModel()
{
}
private string _folderName;
public string FolderName
{
get { return _folderName; }
set
{
_folderName = value;
if (!string.IsNullOrEmpty(_folderName))
InvalidValidFolder();
if (!string.IsNullOrEmpty(_folderName))
ValidateFolder();
OnPropertyChanged("FolderName");
}
}
private void ValidateFolder()
{
if (!Directory.Exists(FolderName))
throw new Exception("Folder does not exist");
}
private void InvalidValidFolder()
{
if (FolderName.ToLower() == @"c:\windows\boot")
throw new Exception("This folder is restricted.");
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Я просто MainWindow
и MainWindowViewModel
.
<DockPanel>
<Grid DockPanel.Dock="Top" Width="Auto" Margin="50">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBox x:Name="textBox" Text="{Binding FolderName, ValidatesOnExceptions=True, ValidatesOnDataErrors=True}" Margin="0,0,0,5" Grid.Column="0" />
<Button Grid.Column="1"
Margin="5,0,5,0"
Width="35"
Content="..."
Click="LocationChoose_Click"/>
</Grid>
<Grid></Grid>
</DockPanel>
Codebehind
public partial class MainWindow : Window
{
public MainWindowViewModel ViewModel {get; set;}
public MainWindow()
{
InitializeComponent();
this.DataContext = ViewModel = new MainWindowViewModel();
}
private void LocationChoose_Click(object sender, RoutedEventArgs e)
{
try
{
FolderBrowserDialog folderDlg = new FolderBrowserDialog();
folderDlg.ShowDialog();
ViewModel.FolderName = folderDlg.SelectedPath;
}
catch (Exception ex)
{
System.Windows.MessageBox.Show(ex.Message);
}
}
}
Однако, еще один вопрос пришел мне на ум. Этот код позади (выше фрагмента) нарушает хороший принцип отсутствия кода для MVVM? Где тонкая линия того, сколько кода у нас может быть в MVVM? Если бы я использовал DelegateCommand PRISM, у меня не было бы доступа к текстовому полю. В таком случае, какое другое решение я могу иметь? – isakavis