首页 > 解决方案 > WPF 应用程序中控制器的位置是什么

问题描述

当今的大多数应用程序都是 Web 应用程序。因此,大多数指南和示例都是为 Web 应用程序编写的。在我工作的地方,我们正在制作 WPF 应用程序,但有一件事我无法弄清楚:

详细说明:

在 Web 应用程序中,UI 通常通过 HTTP 与控制器通信。然后控制器与服务/存储库/等(取决于架构)进行对话。

我还没有看到 WPF 应用程序中 UI 和后端之间通信的清晰示例。

我看到的示例要么使用非常紧密的耦合(通常在教程中),要么使用 HTTP 后端(基本上使它成为一个 Web 应用程序)。所以如果你想从 HTTP 架构中获得松耦合的优势,但它必须在一个应用程序中,我该如何实现呢?

标签: c#wpfmvvm

解决方案


在 MVVM 中,视图绑定到视图模型类。视图模型类可以注入模型或服务。

例如,假设您想显示从某个 REST API 接收到的一些项目的列表。

在视图中,您将定义ItemsControl绑定到视图模型的集合属性的一个:

<ItemsControl ItemsSource="{Binding Items}" />

您可能还有一个按钮,该按钮绑定到负责获取数据的命令:

视图模型可以这样实现:

public class ViewModel : INotifyPropertyChanged
{
    private readonly IRestService _service;

    public ViewModel(IRestService service)
    {
        _service = service;

        GetDataCommand = new RelayCommand(GetData);
    }

    private IEnumerable<string> _items;
    public IEnumerable<string> Items
    {
        get { return _items; }
        set { _items = value; NotifyPropertyChanged(nameof(Items)); }
    }

    public ICommand GetDataCommand { get; }

    private async void GetData(object _)
    {
        var data = await Task.Run(() => _service.GetData());
        Items = data;
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

RelayCommand是 ICommand 接口的自定义实现,它执行Action<object>. 您会在网上找到的大多数实现不支持async/ await,即您不能等待命令。这就是为什么GetData返回void而不是Task在上面的示例中。在后台线程上调用服务方法以保持 UI 响应。


推荐阅读