gpt4 book ai didi

c# - MVVM 模式查询

转载 作者:行者123 更新时间:2023-12-03 10:55:16 24 4
gpt4 key购买 nike

我正在学习带有 MVVM 设计模式的 WPF,并试图了解如何在背后的代码之外完成一些事情。
我有一个登录页面,如下图所示。
enter image description here

我有一个从 http://www.wpftutorial.net/PasswordBox.html 获取的密码控制.

我现在为了简单的理解,想问你我的代码是否在正确的类/设置中正确地遵守 MVVVM 规则和关注点分离。

我目前有一个 if 语句来检查详细信息是否与名称字符串和密码字符串匹配。
代码在后面的代码中。我只是想知道这对于 MVVM 是否正确。我想知道您如何在 ViewModel 中实现这一点?

 private void OK_Click(object sender, RoutedEventArgs e)
{
if (emp.Name == "ep" && emp.Password == "pass")
{
MessageBox.Show("namd and Pw accepted");
//open new page
var HomeScreen = new HomeScreen();
HomeScreen.Show();
}
else
{
//deny access
MessageBox.Show("Incorrect username and password");
}
}

最佳答案

不要在后面的代码中实现按钮单击处理程序,而是使用 ICommand并将其绑定(bind)到 XAML 中的按钮事件。

这是一个非常棒的教程,让我开始使用 MVVM:
WPF Apps With The Model-View-ViewModel Design Pattern

[编辑添加示例代码]

这是一个简单的代码示例,可以完成您的示例所做的工作,但采用 MVVM 风格,根本没有任何代码隐藏代码。

1) 创建一个新的 WPF 解决方案,对于这个小示例,我将其简单命名为“WpfApplication”。

2) 编辑自动创建的MainWindow.xaml的代码:

<Window x:Class="WpfApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:viewModel="clr-namespace:WpfApplication"
Title="MainWindow" Height="234" Width="282">

<!-- Create the ViewModel as the initial DataContext -->
<Window.DataContext>
<viewModel:MainWindowViewModel />
</Window.DataContext>

<Grid>
<TextBox Height="23"
HorizontalAlignment="Left"
Margin="70,31,0,0"
Name="textBox1"
VerticalAlignment="Top"
Width="120"
Text="{Binding Path=Name}"/>
<TextBox Height="23"
HorizontalAlignment="Left"
Margin="70,72,0,0"
Name="textBox2"
VerticalAlignment="Top"
Width="120"
Text="{Binding Path=Password}" />
<Label Content="Name"
Height="28"
HorizontalAlignment="Left"
Margin="22,29,0,0"
Name="label1"
VerticalAlignment="Top" />
<Label Content="PW"
Height="28"
HorizontalAlignment="Left"
Margin="22,70,0,0"
Name="label2"
VerticalAlignment="Top" />
<Button Content="OK"
Height="23"
HorizontalAlignment="Left"
Margin="70,119,0,0"
Name="button1"
VerticalAlignment="Top"
Width="120"
Command="{Binding Path=LoginCommand}"
CommandParameter="{Binding Path=.}"
/>
</Grid>
</Window>

(忽略宽度、高度、边距值,这些只是从我的设计师那里复制和粘贴的,并且经过快速和肮脏的调整,大致看起来像你的屏幕截图;-))

3) 创建将处理您的登录逻辑的命令类。请注意,我没有像 Josh Smith 的教程中那样将它实现为 RelayCommand,但相应地修改代码很容易:
      namespace WpfApplication
{
using System;
using System.Windows;
using System.Windows.Input;

/// <summary>
/// Checks the user credentials.
/// </summary>
public class LoginCommand : ICommand
{

/// <summary>
/// Defines the method to be called when the command is invoked.
/// </summary>
/// <param name="parameter">Data used by the command. If the command does not require data to be passed, this object can be set to null.</param>
public void Execute(object parameter)
{
MainWindowViewModel viewModel = parameter as MainWindowViewModel;

if (viewModel == null)
{
return;
}

if (viewModel.Name == "ep" && viewModel.Password == "pass")
{
MessageBox.Show("namd and Pw accepted");

//open new page
var HomeScreen = new HomeScreen();
HomeScreen.Show();
}
else
{
//deny access
MessageBox.Show("Incorrect username and password");
}
}

/// <summary>
/// Defines the method that determines whether the command can execute in its current state.
/// </summary>
/// <returns>
/// true if this command can be executed; otherwise, false.
/// </returns>
/// <param name="parameter">Data used by the command. If the command does not require data to be passed, this object can be set to null.</param>
public bool CanExecute(object parameter)
{
// Update this for your application's needs.
return true;
}

public event EventHandler CanExecuteChanged;
}
}

4) 现在添加将与 View 通信的 ViewModel 并为其提供命令接口(interface)和值:
    namespace WpfApplication
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows.Input;

/// <summary>
/// TODO: Update summary.
/// </summary>
public class MainWindowViewModel : INotifyPropertyChanged
{
#region Implementation of INotifyPropertyChanged

/// <summary>
/// Occurs when a property value changes.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;

/// <summary>
/// Signal that the property value with the specified name has changed.
/// </summary>
/// <param name="propertyName">The name of the changed property.</param>
protected virtual void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}

#endregion Implementation of INotifyPropertyChanged

#region Backing Fields

/// <summary>
/// Gets or sets the value of Name.
/// </summary>
private string name;

/// <summary>
/// Gets or sets the value of Password.
/// </summary>
private string password;

/// <summary>
/// Gets or sets the value of LoginCommand.
/// </summary>
private LoginCommand loginCommand;

#endregion Backing Fields

#region Constructor

/// <summary>
/// Initializes a new instance of the <see cref="MainWindowViewModel"/> class.
/// </summary>
public MainWindowViewModel()
{
this.loginCommand = new LoginCommand();
}

#endregion Constructor

#region Properties

/// <summary>
/// Gets or sets the name of the user.
/// </summary>
public string Name
{
get
{
return this.name;
}

set
{
if (this.name == value)
{
return;
}

this.name = value;
this.OnPropertyChanged("Name");
}
}

/// <summary>
/// Gets or sets the user password.
/// </summary>
public string Password
{
get
{
return this.password;
}

set
{
if (this.password == value)
{
return;
}

this.password = value;
this.OnPropertyChanged("Password");
}
}

/// <summary>
/// Gets or sets the command object that handles the login.
/// </summary>
public ICommand LoginCommand
{
get
{
return this.loginCommand;
}

set
{
if (this.loginCommand == value)
{
return;
}

this.loginCommand = (LoginCommand)value;
this.OnPropertyChanged("LoginCommand");
}
}

#endregion Properties
}
}

5) 最后别忘了添加一个额外的窗口 HomeScreen它将由 LoginCommand 打开到解决方案。 :-)

关于c# - MVVM 模式查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21626025/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com