UWP 数据绑定不适用于 ViewModel

Kon*_*pas 3 data-binding mvvm inotifypropertychanged uwp uwp-xaml

UWP 和 MVVM 的新手我遇到了一个对你们中的许多人来说似乎很明显的问题。

在项目中,我有3个文件夹命名ViewsViewModelsModels包括一些文件作为图像波纹管看到:

Can't upload image yet (reputation):

http://i.imgur.com/42f5KeT.png

问题: 我正在尝试实施 MVVM。我已经搜索了数小时的文章和视频,但似乎总是遗漏一些东西。我有一些绑定,LoginPage.xaml然后我在里面的一个类中修改Models/LoginPageModel.cs。我的INotifyPropertyChangedLoginPageViewModel.cs 中有一个类,每次我的属性更改时,我都LoginPageModel.cs希望INotifyPropertyChanged该类触发,然后更改LoginPage.xaml视图中的属性。下面我有这些文件的内容。

这是我的LoginPageModel.cs代码示例:

using System;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace App_Name.Models
{
    class LoginPageModel
    {
        private NotifyChanges notify;

        public async void LogIn()
        {
            if (something is true)
                notify.LoginUIVisibility = Visibility.Visible;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的LoginPageViewModel.cs

using System.ComponentModel;
using System.Runtime.CompilerServices;
using Windows.UI.Xaml;

namespace App_Name.ViewModels
{
    public class NotifyChanges : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

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

        private Visibility loginUIVisibility = Visibility.Collapsed;

        public Visibility LoginUIVisibility
        {
            get
            {
                return loginUIVisibility;
            }

            set
            {
                if (value != loginUIVisibility)
                {
                    loginUIVisibility = value;
                    NotifyPropertyChanged("LoginUIVisibility");
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

下面是一个例子LoginPage.xaml

<Page
    x:Class="App_Name.LoginPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App_Name"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:vm="using:App_Name.ViewModels"
    mc:Ignorable="d">

    <Page.DataContext>
        <vm:NotifyChanges/>
    </Page.DataContext>

    <StackPanel Visibility="{Binding LoginUIVisibility}">
Run Code Online (Sandbox Code Playgroud)

这是我的LoginPage.xaml.cs

namespace App_Name
{
    public sealed partial class LoginPage : Page
    {
        private LoginPageModel login;
        public LoginPage()
        {
            InitializeComponent();
            login.LogIn();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我不知道为什么这不起作用。绑定曾经不起作用,但现在在运行时它给了我一个未处理的异常,我认为这与没有为private NotifyChanges notifyprivate LoginPageModel login对象分配任何值有关 ,但我不知道是什么。提前感谢大家的时间!

如果您需要澄清我的问题,请发表评论。谢谢!

Hen*_*man 5

我正在尝试实现 MVVM。

而且你还没有做对。暂时忘记绑定,让我们专注于架构。

按照首字母缩略词,你需要

  • 一个模型。它支持您的业务逻辑,通常由您的后端(数据库)定义。它不应该依赖于(注意)视图或视图模型。轻量级 UWP 应用可以在没有模型层的情况下工作。

  • 一个看法。这是我们希望保持尽可能简单的 XAML 部分,原因是因为它最难测试。

  • 一个视图模型。它的目的是为视图服务。它应该包含视图可以直接绑定到的属性和命令。它会做尽可能多的转换和聚合以保持 View 光照。它通常依赖于(0 个或更多)模型或服务。

鉴于此,您不应该总是为 1 个 ViewModel 提供 1 个模型。一个 ViewModel 可以使用多个 Model,也可以不使用。

很明显,你LoginPageModel.Login()是在错误的地方。Login()应该是您的 ViewModel 上的一个方法(命令)。

你的故事应该是这样的:

  1. 我想要一个登录视图
  2. 所以我需要用 LoginViewModel 来支持它,实现 INPC
  3. ViewModel 可能需要使用 LoginService 或 UserModel。但是在成功登录后它只需要一个 Model 实例。LoginModel 听起来不对。

查看Template10以开始使用 View、ViewModel 和线程安全的 BindableBase。

您也可以在此处查看 MVVM 的完整(可能是顶部)布局的图片。