WPF FolderBrowserDialog using MVVM(without code be

2019-03-06 19:36发布

问题:

Explanation: I have to get FolderBrowserDialog Box once I click the browse button. And In FolderBrowserDialog Box,if I select any folder and click ok,that particular folderpath along with foldername should be shown in the textbox which is beside the browse button....But I didn't get anything once I click Browse button. Please check my code and correct me...

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

回答1:

Do the following changes,

In View.xaml

<Button Content="Browse" Command="{Binding OpenFolderCommand}"/>

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


回答2:

I would write the command like this:

public ICommand OpenFolderCommand { get; private set; }
public MyViewModel() 
{
    this.OpenFolderCommand = new RelayCommand(a=> this.OpenFolder(),p=> CanOpenFolder());
}


回答3:

You should not call the command from the delegated method (OpenFolder()). The command does nothing else than to execute the delegated method when Execute is called, which is done automatically when you click the button.

Also ICommand.CanExecute() is typically called automatically by WPF itself and based on the result in only enables, resp disables the button. You rarely call the CanExecute by yourself in ViewModel. In your case, you want the button always enabled, so you can skip CanExecute, or use p => true expression.

This should work

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


标签: c# wpf mvvm