Mvvm UWP数据绑定不适用于ViewModel
对于UWP和MVVM来说,我是一个相当陌生的人,我遇到了一个对你们中的许多人来说似乎很明显的问题 在我的项目中,我有3个名为Mvvm UWP数据绑定不适用于ViewModel,mvvm,data-binding,uwp,inotifypropertychanged,uwp-xaml,Mvvm,Data Binding,Uwp,Inotifypropertychanged,Uwp Xaml,对于UWP和MVVM来说,我是一个相当陌生的人,我遇到了一个对你们中的许多人来说似乎很明显的问题 在我的项目中,我有3个名为视图、视图模型和模型的文件夹,其中包括一些文件,如下图所示: 尚无法上载图像(声誉): 问题: 我正在尝试实现MVVM。我已经搜索了数小时的文章和视频,但似乎我总是错过一些东西。我在LoginPage.xaml中有一些绑定,然后在Models/LoginPageModel.cs中的类中修改这些绑定。我在LoginPageViewModel.cs中有一个INotifyPro
视图
、视图模型
和模型
的文件夹,其中包括一些文件,如下图所示:
尚无法上载图像(声誉):
问题:
我正在尝试实现MVVM。我已经搜索了数小时的文章和视频,但似乎我总是错过一些东西。我在LoginPage.xaml
中有一些绑定,然后在Models/LoginPageModel.cs
中的类中修改这些绑定。我在LoginPageViewModel.cs中有一个INotifyPropertyChanged
类,每当我的LoginPageModel.cs
中的属性发生更改时,我希望触发INotifyPropertyChanged
类,然后该类将更改LoginPage.xaml
视图中的属性。下面是这些文件的内容
这是我的LoginPageModel.cs
code:
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;
}
}
}
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");
}
}
}
}
}
<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}">
namespace App_Name
{
public sealed partial class LoginPage : Page
{
private LoginPageModel login;
public LoginPage()
{
InitializeComponent();
login.LogIn();
}
}
}
这是我的LoginPageViewModel.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;
}
}
}
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");
}
}
}
}
}
<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}">
namespace App_Name
{
public sealed partial class LoginPage : Page
{
private LoginPageModel login;
public LoginPage()
{
InitializeComponent();
login.LogIn();
}
}
}
下面是LoginPage.xaml
的一个示例:
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;
}
}
}
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");
}
}
}
}
}
<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}">
namespace App_Name
{
public sealed partial class LoginPage : Page
{
private LoginPageModel login;
public LoginPage()
{
InitializeComponent();
login.LogIn();
}
}
}
我不知道这为什么不起作用。绑定过去不起作用,但现在在运行时它给了我一个未处理的异常,我认为这与没有为private NotifyChanges notify
和private LoginPageModel login
对象分配任何值有关,但我不知道是什么。提前感谢大家抽出时间
如果你需要澄清我的问题,请写一条评论。谢谢大家!
以下是对主要课程改革的呼吁:
NotifyChanges NotifyChanges=new NotifyChanges()代码>
notifyChanges.loginuviability=可见性.Visible代码>
通过添加
,您已经在XAML
文件中实例化了notifyChanges
。并使用
向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>
我正在尝试实现MVVM
而且你还没弄对。暂时忘掉绑定吧,让我们关注一下体系结构
在首字母缩略词中,您需要
- 模特儿。它支持您的业务逻辑,通常由后端(数据库)定义。它不应依赖(注意)视图或视图模型。轻量级UWP应用程序可以不使用模型层
- 景色。这是我们希望尽可能简单的XAML部分,因为它最难测试
- 视图模型。它的目的是服务于观点。它应该包含视图可以直接绑定到的属性和命令。它尽可能多地进行转换和聚合,以保持视图的亮度。它通常依赖于(0或更多)模型或服务
考虑到这一点,您不应该总是将1个模型用于1个ViewModel。ViewModel可以使用多个模型,也可以不使用任何模型
很明显,您的LoginPageModel.Login()
位于错误的位置<代码>登录()
应该是ViewModel上的方法(命令)
你的故事应该是这样的:
我想要一个登录视图
所以我需要用一个LoginViewModel来支持它,实现INPC
ViewModel可能需要使用LoginService或UserModel。但在成功登录后,它只需要一个模型实例。LoginModel听起来不太正确李>
了解如何开始使用View、ViewModel和线程安全的BindableBase
您还可以在图片中查看MVVM的完整(可能在顶部)布局。基本上,您正在创建新的notifyChanges对象(ViewModel的名称…),并在其中设置属性,如果is将这个类的不同实例设置为DataContext,为什么您希望UI发生变化?所以这会进入我的初始页面构造函数而不是XAML?如何在ViewModel文件中引用它?这是一种可能的方法,在Constructor(在xaml.cs文件中)中创建ViewModel的实例,保留对它的引用并将其设置为DataContext,现在,当您要处理这个被引用对象的属性时,如果所有内容都在同一个文件中,那么UI应该会发生变化。我的问题是DataContext=newnotifychanges();发生在我的XAML.cs文件中,NotifyChanges()类和修改这些属性的类位于不同的文件中。不同的文件:两个类是NotifyChanges,另一个是修改发生的地方。同样,如何在不创建新实例的情况下,将这些属性从NotifyChanges类引用到同一文件中的上述类?谢谢:)DataContext=newnotifychanges();在上面的示例中没有命名的神秘控件的constructor xaml.cs文件中,然后在不同的对象中,需要引用ViewModel(只需更改其属性)或控件(xaml.cs)实例-如果是这样,则获取其DataContext(例如,var ViewModel=sampleControl.DataContext as NotifyChanges;)并使用其属性提示:阅读MVVM中的视图优先和视图模型优先方法