WPF MVVM应用程序的设计

时间:2014-06-03 16:33:52

标签: c# wpf mvvm icommand

我一直在使用MVF(模型视图ViewModel)与WPF进行大量研究。我正在开发一个桌面应用程序。该应用程序包含一个主窗口。这个主窗口有一些按钮可以做某事。此外,还有一个按钮可以打开OpenFileDialog框。

目前,这是主窗口绑定到的ViewModel:

MainWindowPresenter Class

namespace BMSVM_Simulator.ViewModel
{
    class MainWindowPresenter : ObservableObject
    {
        private bool logLoaded; // true if a log is currently loaded, false otherwise

        public MainWindowPresenter()
        {
            logLoaded = true;
        }

        public ICommand load_data_button_pressed
        {
            get { return new DelegateCommand(doLoadData);  }
        }

        private void doLoadData()
        {
            // DO LOAD DATA COMMANDS
        }

        public ICommand exit_button_pressed
        {
            get { return new DelegateCommand(doExit); }
        }

        private void doExit()
        {
            // DO EXIT COMMANDS
        }
    }
}

问题1 :我担心这是“错误的”实施。每个按钮是否正确(每个MVVM)具有类型ICommand的属性,然后是实现该功能的相应方法?一个包含很多按钮的主窗口会有一个非常大的ViewModel类,没有?

问题2 :如果其中一个按钮是文件 - >打开文件按钮。因此,在这种情况下,它将打开一个新的OpenFileDialog窗口。这会以我之前完成的方式完成(即具有public ICommand open_file_dialog_button_pressed属性和相应的public void doOpenFileDialog()方法吗?这似乎是我将打开文件对话框的“视图”混合到ViewModel,虽然视图已由内置的wpf OpenFileDialog类定义。

问题3 :我们的应用程序的每个“视图”应该只有一个单个“presenter”类(它是ViewModel的一部分)才是真的那种观点与之相关?在上面的示例中,我的主窗口视图仅绑定 MainWindowPresenter类。如果我要创建另一个视图(比如在其自己的弹出窗口中使用Microsoft的动态数据显示库生成的图形),我需要在我的ViewModel中添加一个“presenter”类,对吗?

非常感谢! 富

作为参考,我已经包含了这些类,但它们可能没用:

DelegateCommand班级

namespace BMSVM_Simulator.ViewModel
{
    public class DelegateCommand : ICommand
    {
        private readonly Action _action;

        public DelegateCommand(Action action)
        {
            _action = action;
        }

        public void Execute(object parameter)
        {
            _action();
        }

        public bool CanExecute(object parameter)
        {
            return true;
        }

#pragma warning disable 67
        public event EventHandler CanExecuteChanged;
#pragma warning restore 67
    }
}

ObservableObject班级

namespace BMSVM_Simulator.ViewModel
{
    class ObservableObject : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        //basic ViewModelBase
        internal void RaisePropertyChanged(string prop)
        {
            if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(prop)); }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

1)是的,这是正确的。您需要为每个命令创建一个命令属性。但是由于你的relay命令,你不需要直接实现它。为防止ViewModel破坏,我建议将所有命令移动到单独的CommandsViewModel中作为命令源。然后你的视图会绑定它。

2)可以使用CommandBinding属性通过路由命令在XAML中打开对话框。所以任务仍然在视图中。您基本上尝试避免对任何视图相关对象的依赖。 .NET为常见目的提供了一些现成的命令(MSDN - ApplicationCommands

3)当然,您可以在视图之间共享ViewModel。这是将实现构建到模型视图ViewModel中以独立于更改和可重用性的一个原因。当多个视图同时更新同一个源时,它可能变得至关重要。