WPF应用中的FolderBrowserDialog抛出应用异常而不是绑定异常

本文关键字:异常 应用 绑定 FolderBrowserDialog WPF | 更新日期: 2023-09-27 18:06:15

你好,我正在使用WPF application中的System.Windows.Forms.FolderBrowserDialog来选择用户计算机中的文件夹。选中的文件夹将显示在TextBox中,并在视图模型中进行验证。

我试图在TextBox下面显示无效文件夹Error Template消息,用于以下场景:

  1. 如果文件夹不存在且不可访问。
  2. 如果用户选择的文件夹是系统文件夹。对于本例,我将值硬编码为@"c:'windows'boot"

我注意到的是:如果我输入一个不存在的文件夹,我将得到绑定异常,它允许我设置错误模板。

但是如果我选择一个用户没有访问权限的驱动器,或者我选择@"c:'windows'boot",我将得到一个异常,这个异常要么在App.xaml unhandle异常中被捕获,要么如果你有一个try catch(文件夹设置的地方),它将在那里被捕获。如何将其作为绑定异常?在我决定将其作为try 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));
            }
        }
    }

我只有MainWindowMainWindowViewModel

<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>
后台代码

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);
            }
        }
    }

WPF应用中的FolderBrowserDialog抛出应用异常而不是绑定异常

如果有人感兴趣的话,我找到答案了。

我把后面的代码改成:

private void LocationChoose_Click(object sender, RoutedEventArgs e)
{
    FolderBrowserDialog folderDlg = new FolderBrowserDialog();
    folderDlg.ShowDialog();
    //ViewModel.FolderName = folderDlg.SelectedPath;
    textBox1.Text = folderDlg.SelectedPath;
    BindingExpression exp = this.textBox1.GetBindingExpression(System.Windows.Controls.TextBox.TextProperty);
    exp.UpdateSource();
}

将其视为绑定异常。现在我可以应用模板了。感谢您的宝贵时间。