c# - 在 MVP-VM 事件或按钮单击中使用 WPF xaml

标签 c# wpf xaml icommand

好吧,我对 WPF 还是(非常)陌生,但是使用 Win-forms 已经 13 年了,所以没有新手。 我正在编写一个新系统,并决定使用 MVP-VM 模式打破与 WPF 的僵局,因为我熟悉 MVP。

现在我也在重用我自己的(复合)架构,该架构在项目中具有与 Presenter 和 View 模型分开的 UI 或表示层。这种方法的主要好处之一是 Presenter 层或 Base 层具有所有表示/命令/ Controller 逻辑,并且不涉及 UI 事务。主要想法是该层不引用任何 UI 程序集,如 Winforms 或 WPF。

问题: 在 Xaml 中,我有一个菜单项“退出”,我想将其绑定(bind)到 View 模型。我见过的每个示例都使用 ICommand.. 它位于 Presentation.core 中... View 模型位于表示层中,因此没有对 Presentation.Core 的引用..

到目前为止的 Xaml 是

<Window x:Class="Homestead.Wpf.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="244" Width="490" xmlns:xcad="http://schemas.xceed.com/wpf/xaml/avalondock">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="23"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="23" />
    </Grid.RowDefinitions>
    <Menu Grid.Row="0">
        <MenuItem Header="File">
            <MenuItem Header="Exit"  />
        </MenuItem> 
    </Menu>
    <StatusBar Grid.Row="2"  >
        <StatusBarItem   >
            <TextBlock  Text="{Binding Path=StatusMessage}" />
        </StatusBarItem>
        <StatusBarItem  HorizontalAlignment="Right" MinWidth="120">
            <TextBlock  Text="{Binding Path=UserName}" />
        </StatusBarItem>
    </StatusBar>
</Grid>

目前的 View 模型是

public class ShellViewModel : ViewModelBase
{

    #region Private Variables

    private string _status = string.Empty;
    private string _userName;

    #endregion

    #region Public Properties

    public string StatusMessage
    {
        get { return _status; }
        set
        {
            _status = value;
            OnPropertyChanged("StatusMessage");
        }
    }

    public string UserName
    {
        get { return _userName; }
        set
        {
            _userName = value;
            OnPropertyChanged("UserName");
        }
    }


    #endregion

    #region Commands

    // No reference to ICommand... WTF

    #endregion
}
  1. 是否有替代此模式的方法...(不使用代码隐藏)
  2. 这如何与在运行时添加的菜单项一起使用,有趣的是有一种方法。

我必须重新设计或打破设计模式才能使用 WPF 吗?请指导我。

我可以看到一种可能性,那就是将 ViewModel 和 View 接口(interface)出来。我有一个创建 Presenter 的 Controller,通常将 View 的实现传递给 Presenter。即典型的 Presenter 构造函数是

    public ErrorMessagePresenter(IErrorMessageView view)
    {
        View = view;
        View.Presenter = this;            
    }

Controller 代码是这样的

    public ErrorMessagePresenter CreateErrorPresenter()
    {
        return new ErrorMessagePresenter(_viewFactory.CreateErrorMessageView());
    }

现在我知道这是相反的,但从字面上看,UI 层只关心 UI 问题,包括导航在内的所有其他内容都在 Base 层或下面处理..

最佳答案

WPF 中最常见的模式是 Model-View-ViewModel,在这种模式中,presenter 已被移除,取而代之的是知识更丰富的 View 模型,它确实知道 ICommand(这是一个契约,共享通过 View 层作为一种交流 Action 的方式,这证明了 View 模型知道它是合理的)。

您可以尝试通过实现行为和数据触发器来强制应用程序不使用 ICommand,这些触发器根据 UI 中的操作在 View 模型中执行操作,但这需要更多的编码,而不仅仅是绑定(bind),而且它不可扩展或者如果您打算在未来继续开发 WPF 应用程序(或与此相关的 Windows 应用商店应用程序,通常也使用 MVVM),则可持续发展。

我建议考虑使用 NuGet 在您的项目中加入像 MVVM-light 这样的框架,这样您就可以从一组完善的类、模式和实用程序的基础开始,这些类、模式和实用程序已经适应 WPF 作为一种技术多年来,而不是试图将您熟悉的“球形”框架敲入 WPF(形象地说)的“方形”空腔。

当我开始使用它时,我学到了一个艰难的方法,试图将我的经验和习惯从 WinForms 带到 WPF 只会带来麻烦,所以你越早开始接受你所做的大部分工作都会成功的想法'适用于 WPF,对您的精神健康更好。

当然,模式就是模式,它们可以在多种环境中以不同的方式应用,但现实情况是 WPF 已经有了让某些事情以某种方式工作的插件,并且试图违背它只会给开发人员和架构师更多的工作,所以最好顺其自然,适应 XAML 世界中最常见的做事方式。

关于c# - 在 MVP-VM 事件或按钮单击中使用 WPF xaml,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27371365/

相关文章:

c# - 比较具有毫秒精度的日期时间

c# - 处理与外部登录提供商的 claim

c# - 创建自定义 wpf 事件

wpf - MVVM-应该将动态生成和加载XAML的代码放在哪里?

wpf - 如何在 View 模型中使用来自 xaml 的 wpf 事件而无需隐藏代码?

c# - 跨不同程序集版本传递类对象

wpf - VS 2012 在加载 XAML 设计器时挂起

wpf - DataGrid内的Combobox,隐藏Combobox上的选定项

c# - WPF ListView : Set the Background color for specific items when Focusable is set to false

C# listview 最大行数