説明 ブラウズボタンをクリックすると、FolderBrowserDialog Boxが表示されます。そして、FolderBrowserDialog Boxでは、任意のフォルダを選択してokをクリックすると、フォルダ名と一緒にその特定のfolderpathは、ブラウズボタンの横にあるテキストボックスに表示されるべきである...しかし、私はしなかった&#39をクリックすると何も得ることができません。 私のコードをチェックし、修正してください。
View.xaml:
<Window.... xmlns:VM="clr-namespace:myproject.myViewModel"
... >
<Window.DataContext><VM:myViewModel/>
<Grid>...
<TextBlock Text="Folder to save files" VerticalAlignment="Center" />
<TextBox Text="{Binding Path=FoldernameWithPath , UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Height="26" IsReadOnly="True" VerticalContentAlignment="Center" Width="150" />
<Button Content="Browse" Height="26" VerticalAlignment="Bottom" MinWidth="45" Command="{Binding OpenFolderCommand}" />
</Grid>
</window>
ViewModel.cs
public ICommand OpenFolderCommand
{
get => new RelayCommand(a => this.OpenFolder(), p => CanOpenFolder());
}
private string _foldernameWithPath;
public string FoldernameWithPath
{
get { return _foldernameWithPath; }
set
{
if (value == _foldernameWithPath)
{
return;
}
else
{
_foldernameWithPath = value;
OnPropertyChanged("FoldernameWithPath");
}
}
}
public bool CanOpenFolder()
{
return true;
}
private void OpenFolder()
{
FolderBrowserDialog openFolderDialog = new FolderBrowserDialog();
if (openFolderDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK && OpenFolderCommand.CanExecute(openFolderDialog.SelectedPath))
{
OpenFolderCommand.Execute(openFolderDialog.SelectedPath);
FoldernameWithPath = openFolderDialog.SelectedPath;
}
}
以下の変更を行ってください。
View.xamlで
<Button Content="Browse" Command="{Binding OpenFolderCommand}"/>
ViewModel.cs で
public bool CanOpenFolder()
{
return true;
}
private void OpenFolder()
{
FolderBrowserDialog openFolderDialog = new FolderBrowserDialog();
if (openFolderDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK && OpenFolderCommand.CanExecute(openFolderDialog.SelectedPath))
{
//OpenFolderCommand.Execute(openFolderDialog.SelectedPath);
FoldernameWithPath = openFolderDialog.SelectedPath;
}
}
デリゲートメソッド(OpenFolder()
)からコマンドを呼び出してはいけません。このコマンドは、ボタンをクリックしたときに自動的に実行される Execute が呼ばれたときにデリゲートメソッドを実行すること以外には何も行いません。
また、ICommand.CanExecute()
は、通常、WPF自身が自動的に呼び出し、その結果に基づいてボタンを有効にしたり、無効にしたりするだけです。ViewModelの中で、自分でCanExecuteを呼び出すことはほとんどないでしょう。あなたの場合、ボタンを常に有効にしたいので、CanExecuteをスキップするか、p => true
式を使用することができます。
これは、以下のように動作するはずです。
xaml:
<TextBox Text="{Binding Path=FoldernameWithPath}" IsReadOnly="True" />
<Button Content="Browse" Command="{Binding OpenFolderCommand}" />
viewmodel:
public ICommand OpenFolderCommand {get;} = new RelayCommand(p => OpenFolder());
private string _foldernameWithPath;
public string FoldernameWithPath
{
get { return _foldernameWithPath; }
set
{
if (value == _foldernameWithPath) return
_foldernameWithPath = value;
OnPropertyChanged("FoldernameWithPath");
}
}
public void OpenFolder()
{
FolderBrowserDialog openFolderDialog = new FolderBrowserDialog();
if (openFolderDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
FoldernameWithPath = openFolderDialog.SelectedPath;
}
}