UWP 数据绑定不适用于 ViewModel
UWP Data-Binding not working with ViewModel
我是 UWP 和 MVVM 的新手,我遇到了一个对你们中的许多人来说似乎显而易见的问题。
在我的项目中,我有 3 个名为 Views
、ViewModels
和 Models
的文件夹,其中包含一些文件,如下图所示:
Can't upload image yet (reputation):
http://i.imgur.com/42f5KeT.png
The problem:
I am trying to implement MVVM. I have searched hours for articles and videos but it seems I am always missing something. I have some bindings in the LoginPage.xaml
which I then modify in a class inside Models/LoginPageModel.cs
. I have an INotifyPropertyChanged
class in my LoginPageViewModel.cs where every time a property changes in my LoginPageModel.cs
I want the INotifyPropertyChanged
class to trigger which will then change the property in the LoginPage.xaml
View. Below I have the content of those files.
这是我的 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;
}
}
}
这是我的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");
}
}
}
}
}
下面是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}">
这是我的 LoginPage.xaml.cs
:
namespace App_Name
{
public sealed partial class LoginPage : Page
{
private LoginPageModel login;
public LoginPage()
{
InitializeComponent();
login.LogIn();
}
}
}
I don't know why this is not working. Bindings used not to work, but now at runtime it gives me an unhandled exception and I think it has to do with not assigning any value to the private NotifyChanges notify
and private LoginPageModel login
objects, but I don't know what. Thanks everyone for your time in advance!
如果您需要澄清我的问题,请发表评论。谢谢!
And here is the call for change in the main class:
NotifyChanges notifyChanges = new NotifyChanges();
notifyChanges.LoginUIVisibility = Visibility.Visible;
您已通过添加 <vm:NotifyChanges/>
在 XAML
文件中实例化 notifyChanges
。并使用 <StackPanel Visibility="{Binding LoginUIVisibility}">
添加到 StackPanel 的绑定。但是你创建了一个新的notifyChanges
,你并没有将新的notifyChanges
绑定到StackPanel
。所以它不会工作。您可以像下面的代码一样初始化 viewModel
。
主页
private LoginViewModel viewModel;
public MainPage()
{
this.InitializeComponent();
viewModel = this.DataContext as LoginViewModel;
}
private void showDetail_Click(object sender, RoutedEventArgs e)
{
viewModel.LoginUIVisibility = Visibility.Visible;
}
MainPage.xaml
<Page.DataContext>
<vm:LoginViewModel />
</Page.DataContext>
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Button x:Name="loginButon" Content="Login" Visibility="{Binding LoginUIVisibility}" />
<Button x:Name="showDetail" Content="Show" Click="showDetail_Click" />
</StackPanel>
I am trying to implement MVVM.
而且你还没有做对。暂时忘掉绑定,让我们关注架构。
按照首字母缩略词,你需要
一个模型。它支持您的业务逻辑,通常由您的后端(数据库)定义。它不应该依赖于(注意)视图或视图模型。轻量级 UWP 应用程序可以在没有模型层的情况下运行。
一个视图。这是我们希望尽可能简单的 XAML 部分,a.o。原因是因为它最难测试。
一个视图模型。它的目的是为视图服务。它应该包含视图可以直接绑定到的属性和命令。它尽可能多地进行转换和聚合以保持 View 轻盈。它通常依赖于(0 个或更多)模型或服务。
鉴于此,您不应该总是为 1 个 ViewModel 使用 1 个模型。一个 ViewModel 可以使用多个模型,或者 none。
很明显你的LoginPageModel.Login()
放错地方了。 Login()
应该是您的 ViewModel 上的一个方法(命令)。
你的故事应该是这样的:
- 我想要一个登录视图
- 所以我需要用 LoginViewModel 来支持它,实现 INPC
- ViewModel 可能需要使用 LoginService 或 UserModel。但是在成功登录后它只需要一个模型实例。 LoginModel 听起来不对。
查看 Template10 以开始使用 View、ViewModel 和线程安全的 BindableBase。
您还可以查看图片 以了解 MVVM 的完整(可能在顶部)布局。
我是 UWP 和 MVVM 的新手,我遇到了一个对你们中的许多人来说似乎显而易见的问题。
在我的项目中,我有 3 个名为 Views
、ViewModels
和 Models
的文件夹,其中包含一些文件,如下图所示:
Can't upload image yet (reputation):
http://i.imgur.com/42f5KeT.png
The problem: I am trying to implement MVVM. I have searched hours for articles and videos but it seems I am always missing something. I have some bindings in the
LoginPage.xaml
which I then modify in a class insideModels/LoginPageModel.cs
. I have anINotifyPropertyChanged
class in my LoginPageViewModel.cs where every time a property changes in myLoginPageModel.cs
I want theINotifyPropertyChanged
class to trigger which will then change the property in theLoginPage.xaml
View. Below I have the content of those files.
这是我的 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;
}
}
}
这是我的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");
}
}
}
}
}
下面是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}">
这是我的 LoginPage.xaml.cs
:
namespace App_Name
{
public sealed partial class LoginPage : Page
{
private LoginPageModel login;
public LoginPage()
{
InitializeComponent();
login.LogIn();
}
}
}
I don't know why this is not working. Bindings used not to work, but now at runtime it gives me an unhandled exception and I think it has to do with not assigning any value to the
private NotifyChanges notify
andprivate LoginPageModel login
objects, but I don't know what. Thanks everyone for your time in advance!
如果您需要澄清我的问题,请发表评论。谢谢!
And here is the call for change in the main class:
NotifyChanges notifyChanges = new NotifyChanges();
notifyChanges.LoginUIVisibility = Visibility.Visible;
您已通过添加 <vm:NotifyChanges/>
在 XAML
文件中实例化 notifyChanges
。并使用 <StackPanel Visibility="{Binding LoginUIVisibility}">
添加到 StackPanel 的绑定。但是你创建了一个新的notifyChanges
,你并没有将新的notifyChanges
绑定到StackPanel
。所以它不会工作。您可以像下面的代码一样初始化 viewModel
。
主页
private LoginViewModel viewModel;
public MainPage()
{
this.InitializeComponent();
viewModel = this.DataContext as LoginViewModel;
}
private void showDetail_Click(object sender, RoutedEventArgs e)
{
viewModel.LoginUIVisibility = Visibility.Visible;
}
MainPage.xaml
<Page.DataContext>
<vm:LoginViewModel />
</Page.DataContext>
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Button x:Name="loginButon" Content="Login" Visibility="{Binding LoginUIVisibility}" />
<Button x:Name="showDetail" Content="Show" Click="showDetail_Click" />
</StackPanel>
I am trying to implement MVVM.
而且你还没有做对。暂时忘掉绑定,让我们关注架构。
按照首字母缩略词,你需要
一个模型。它支持您的业务逻辑,通常由您的后端(数据库)定义。它不应该依赖于(注意)视图或视图模型。轻量级 UWP 应用程序可以在没有模型层的情况下运行。
一个视图。这是我们希望尽可能简单的 XAML 部分,a.o。原因是因为它最难测试。
一个视图模型。它的目的是为视图服务。它应该包含视图可以直接绑定到的属性和命令。它尽可能多地进行转换和聚合以保持 View 轻盈。它通常依赖于(0 个或更多)模型或服务。
鉴于此,您不应该总是为 1 个 ViewModel 使用 1 个模型。一个 ViewModel 可以使用多个模型,或者 none。
很明显你的LoginPageModel.Login()
放错地方了。 Login()
应该是您的 ViewModel 上的一个方法(命令)。
你的故事应该是这样的:
- 我想要一个登录视图
- 所以我需要用 LoginViewModel 来支持它,实现 INPC
- ViewModel 可能需要使用 LoginService 或 UserModel。但是在成功登录后它只需要一个模型实例。 LoginModel 听起来不对。
查看 Template10 以开始使用 View、ViewModel 和线程安全的 BindableBase。
您还可以查看图片