【问题标题】:updating text with filename with path via OpenFileDialog using MVVM and WPF使用 MVVM 和 WPF 通过 OpenFileDialog 更新带有文件名和路径的文本
【发布时间】:2011-11-01 10:21:27
【问题描述】:

我有一个带有路径的文件名文本框。用户使用 OpenFileDialog 找到文件后,此文本框应填充文件名。当用户直接输入带有路径的文件名而不是从文件对话框中选择时,此文本也应该起作用。

由于我正在学习 MVVM,我很难弄清楚如何使用文件名/路径更新文本框。我尝试了我能想到的一切。

我期待 onPropertyChanged(“FilenameWithPath”) 应该注意这个问题。有人可以告诉我如何处理这个问题吗?

见下方代码

文件浏览视图.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}"  />

文件浏览视图.xaml.cs

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


}

文件浏览模型

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

}

文件浏览视图模型

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

【问题讨论】:

  • 我建议使用Microsoft.Win32.OpenFileDialog 而不是System.Windows.Forms.OpenFileDialog() 所建议的MSDN

标签: wpf mvvm textbox openfiledialog


【解决方案1】:

您只需要在命令的 Execute 函数中设置 FileNameWithPath。 FileNameWithPath 的设置器应该调用 OnPropertyChanged。您不必从命令的 Execute 函数中调用它。

【讨论】:

    【解决方案2】:

    编辑:确保将数据上下文设置为视图模型而不是模型,因为两者都具有 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(如我的评论中所建议的那样)。

    【讨论】:

    • 我无法让它工作。我已经在我的帖子中重申了这个问题。
    【解决方案3】:

    最后,我能够通过添加名为 RelayCommand 的新类来解决此问题。我已经修改了 _browseCommand 使用中继命令的 get 块,如下所示。

    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      
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-18
      • 2013-05-12
      • 1970-01-01
      相关资源
      最近更新 更多