0

こんにちは、ユーザーのコンピューターでフォルダーを選択するためにを使用しSystem.Windows.Forms.FolderBrowserDialogています。WPF application選択したフォルダーが に表示されTextBox、ビュー モデルでも検証されます。

次のシナリオの下に、無効なフォルダーError Templateメッセージを表示しようとしています。TextBox

  1. フォルダが存在せず、アクセスできない場合。
  2. ユーザーがシステム フォルダーであるフォルダーを選択した場合。この例では、値を としてハードコーディングしました@"c:\windows\boot"

私が気づいているのは、存在しないフォルダーを入力すると、エラー テンプレートを設定できるバインド例外が発生することです。

しかし、ユーザーがアクセスできないドライブを選択した場合、または unhandle 例外@"c:\windows\boot"でキャッチされた例外が発生するか、try catch (フォルダーが設定されている場所) がある場合はそこでキャッチされます。App.xamlどうすればこれを拘束力のある例外として持つことができますか? それを 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));
            }
        }

    }

私は と を持っ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>

コードビハインド

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

1 に答える 1

0

誰かが興味を持っているなら、答えを得ました。

コードビハインドを次のように変更しました。

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

これはバインディング例外として扱います。これで、テンプレートを適用できます。御時間ありがとうございます。

于 2013-03-28T19:20:51.580 に答える