【问题标题】:Does MVVM pattern in WPF allow to manage click event in XAML?WPF 中的 MVVM 模式是否允许在 XAML 中管理单击事件?
【发布时间】:2021-07-10 16:12:20
【问题描述】:

事件管理如何使用 MVVM 模式在 WPF 中工作?我真的应该避免使用直接事件管理吗? 示例:正在构建这样的视图:

<Grid>
    <Button Click="GO_Button_Click" Content="Go" Margin="39,143,503,250"/>
    <TextBox x:Name="outputFolder" Margin="321,182,35,211" Text="{Binding outputFolderPath}"/>
</Grid>

拥有这样的视图模型:

using System.ComponentModel;
using System.Windows;

namespace FirstWpfApp
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        #region variables
        public string outputFolderPath { get; set; }
        #endregion

        #region events
        private void GO_Button_Click(object sender, RoutedEventArgs e)
        {
            outputFolderPath = "Some data";
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(outputFolderPath)));
        }

        #endregion

        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
}

难道我不能更好地实现 MVVM 模式,避免从视图中调用“GO_Button_Click”方法吗?

【问题讨论】:

    标签: c# wpf design-patterns mvvm desktop-application


    【解决方案1】:

    按钮具有“Command”属性,因此您可以将其与实现“ICommand”接口的类绑定。请检查以下文档。 ICommand MVVM implementation.

    另外,您似乎将 MainWindow 本身用作 DataContext。这不是 MVVM 方式。我认为这种方式只是WPF绑定的做法。如果要实现 MVVM 部分,首先应将窗口的ViewModel 设置为代表应用程序领域知识的窗口,并将 MainWindow 的DataContext 设置为ViewModel

    【讨论】:

      【解决方案2】:

      您的 XAML 应如下所示,

      <Button Command="{Binding Button1Command}" Content="GO"/>
      

      还有 MainWindow.xaml.cs 中的代码。这里 MainVM 是 ViewModel 的名称。

          public partial class MainWindow : Window {
              MainVM _vm;
              public MainWindow() {
                  InitializeComponent();
                  _vm = new MainVM(); //Also you handle it by Singleton instance
                  base.DataContext = _vm;
              } 
          }
      

      现在让我们看看 MainVM 的样子,

          public class MainVM : INotifyPropertyChanged {
              public DelegateCommand Button1Command { get; set; }
              public MainVM() {
                  Button1Command = new DelegateCommand(onButton1Command);
              }
              private void onButton1Command(object obj) {
                  //Your Code when Go button press
              }
              
      
              #region INotifyPropertyChanged Members
              public event PropertyChangedEventHandler PropertyChanged;
              protected Action<PropertyChangedEventArgs> RaisePropertyChanged() {
                  return args => PropertyChanged?.Invoke(this, args);
              }
      
              #endregion
          }
      

      这里是实现ICommand接口的DelegateCommand类,

      public class DelegateCommand : ICommand {
              private readonly Predicate<object> _canExecute;
              private readonly Action<object> _execute;
      
              public event EventHandler CanExecuteChanged;
      
              public DelegateCommand(Action<object> execute)
                  : this(execute, null) {
              }
      
              public DelegateCommand(Action<object> execute,
                             Predicate<object> canExecute) {
                  _execute = execute;
                  _canExecute = canExecute;
              }
      
              public bool CanExecute(object parameter) {
                  if (_canExecute == null) {
                      return true;
                  }
      
                  return _canExecute(parameter);
              }
      
              public void Execute(object parameter) {
                  _execute(parameter);
              }
      
              public void RaiseCanExecuteChanged() {
                  CanExecuteChanged?.Invoke(this, EventArgs.Empty);
              }
          }
      

      【讨论】:

        猜你喜欢
        • 2013-07-08
        • 1970-01-01
        • 2011-05-12
        • 1970-01-01
        • 1970-01-01
        • 2010-12-12
        • 2021-12-13
        • 1970-01-01
        • 2015-02-06
        相关资源
        最近更新 更多