обновление текста с именем файла с путем через OpenFileDialog, используя MVVM и WPF - PullRequest
1 голос
/ 22 августа 2011

У меня есть текстовое поле для имени файла с путем.После того, как пользователь найдет файл с помощью OpenFileDialog, это текстовое поле должно быть заполнено именем файла.Этот текст также должен работать, когда пользователь вводит имя файла с путем непосредственно, а не выбирает из диалогового окна файла.

Поскольку я изучаю MVVM, мне трудно понять, как обновить текстовое поле с именем файла / путем.Я перепробовал все, что мог придумать.

Я ожидал, что onPropertyChanged («FilenameWithPath») должен решить эту проблему.Может кто-нибудь показать мне, как бороться с этой проблемой?

См. Код ниже

FileBrowseView.xaml

<TextBox  Height="23" HorizontalAlignment="Left" Margin="113,22,0,0" 
               Name="txtFilenameWithPath" 
               Text="{Binding Path=FilenameWithPath, 
               UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
               VerticalAlignment="Top" Width="300" />
<Button 
        Content="Browse..." 
        Height="30" 
        HorizontalAlignment="Left" 
        Margin="433,20,0,0" 
        Name="btnBrowse" 
        VerticalAlignment="Top"
        Width="142" 
        Command="{Binding Path=BrowseCommand}"  />

FileBrowseView.xaml.cs

public partial class FileBrowseView : Window
{
    public FileBrowseView()
    {
        InitializeComponent();
        DataContext = new FileBrowseViewModel();
    }


}

FileBrowseModel

public class FileBrowseModel
{
  private string _filenameWithPath = string.Empty;
    public string FilenameWithPath
    {
        get { return _filenameWithPath; }
        set
        {
            if (value == _filenameWithPath)
                return;
            else
                _filenameWithPath = value;
        }
    }

}

FileBrowseViewModel

public class FileBrowseViewModel  : INotifyPropertyChanged 
{   
  private string _filenameWithPath = string.Empty;
  public string FilenameWithPath
  {
        get { return _filenameWithPath; }
        set
        {
            if (value == _filenameWithPath)
                return;
            else
                _filenameWithPath = value;
            OnPropertyChanged("FilenameWithPath"); 
        }
    }

    private ICommand _browseCommand;
    public ICommand BrowseCommand
    {
        get
        {
            if (_browseCommand == null)
                _browseCommand = new DoBrowse();
            return _browseCommand;
        }
        set
        {
            _browseCommand = value;
            OnPropertyChanged("FilenameWithPath"); 
        }
    }


    private class DoBrowse : ICommand
    {
        public bool CanExecute(object parameter) { return true; }
        public event EventHandler CanExecuteChanged;
        public void Execute(object parameter)
        {
            var filedialog = new System.Windows.Forms.OpenFileDialog();
            DialogResult fresult = filedialog.ShowDialog();

            if (fresult == System.Windows.Forms.DialogResult.OK)
            {
                 FilenameWithPath = filedialog.FileName;
                //I am trying to assign value i got from OpenFileDialog to 
                // FilenameWithPath property
                //complier says "Cannot access non static member of outer type 
                   'MyProject.FileBrowseViewModel' via 
                  nested type 'MyProject.FileBrowseViewModel.DoBrowse

                onPropertyChanged(“FilenameWithPath”);                    
            }
        }
    }

   public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

Ответы [ 3 ]

1 голос
/ 22 августа 2011

Вам просто нужно установить FileNameWithPath в функции выполнения вашей команды. И установщик для FileNameWithPath должен вызывать OnPropertyChanged. Вам не нужно вызывать это из функции Execute вашей команды.

0 голосов
/ 23 августа 2011

Наконец я смог решить эту проблему, добавив новый класс с именем RelayCommand. Я изменил блок get _browseCommand, используя команду relay, как показано ниже.

private ICommand _browseCommand;
public ICommand BrowseCommand
{
  get{
    if (_browseCommand == null){
        _browseCommand = new RelayCommand(
                                         a => this.DoBrowseFolder(),
                                         p => this.CheckCondition());
    }

    return _browseCommand;
   }

    set
    {   _browseCommand = value;
        OnPropertyChanged("FilenameWithPath");
    }
   }


    public bool CheckCondition () {
    //Check condition here if needed        
        return true;
    }


    private void DoBrowseFolder(){
        var filedialog = new System.Windows.Forms.OpenFileDialog();
        DialogResult fresult = filedialog.ShowDialog();

        if (fresult == System.Windows.Forms.DialogResult.OK)
        {
            FilenameWithPath = filedialog.FileName;
            OnPropertyChanged("FilenameWithPath ");
        }

    }

Командный класс реле

public class RelayCommand : ICommand
{

    #region Fields
    readonly Action<object> _execute;
    readonly Predicate<object> _canExecute;
    #endregion // Fields

    #region Constructors      
    public RelayCommand(Action<object> execute, Predicate<object> canExecute){
        if (execute == null)             
            throw new ArgumentNullException("execute");          
        _execute = execute;         
        _canExecute = canExecute;     
    }     

    #endregion // Constructors      
    #region ICommand Members      
    [DebuggerStepThrough]     
    public bool CanExecute(object parameter)     {         
        return _canExecute == null ? true : _canExecute(parameter);     
    }      

    public event EventHandler CanExecuteChanged     
    {         
        add { CommandManager.RequerySuggested += value; }         
        remove { CommandManager.RequerySuggested -= value; }     
    }      

    public void Execute(object parameter)     {         
        _execute(parameter);     
    }      
    #endregion // ICommand Members      
}
0 голосов
/ 23 августа 2011

РЕДАКТИРОВАТЬ : убедитесь, что вы устанавливаете контекст данных как модель представления, а не модель, поскольку оба имеют свойства FilenameWithPath. Если бы вы делали это, то привязка не удалась бы, потому что все еще есть свойство для привязки. В противном случае:

Внести следующие изменения:

public string FilenameWithPath
{
   get { return _filenameWithPath; }
   set
   {
       if (value == _filenameWithPath)
           return;
       else
       {
           _filenameWithPath = value;
           OnPropertyChanged("FilenameWithPath");
       }
   }
}

и

if (fresult == System.Windows.Forms.DialogResult.OK)
{
    FilenameWithPath = filedialog.FileName;
}

Это должно исправить вашу проблему. Кроме того, рассмотрите возможность изменения того, какое диалоговое окно вы используете, поскольку это WPF (как предложено в моем комментарии).

...