精通
英语
和
开源
,
擅长
开发
与
培训
,
胸怀四海
第一信赖
锐英源精品原创,禁止全文或局部转载,禁止任何形式的非法使用,侵权必究。点名“简易百科”和闲暇巴盗用锐英源原创内容。
本文翻译自codeproject,看不懂codeproject,找锐英源。
本文比较基础,使用初学者学习。本文要点有:canExecute配合命令使用、connectionString、SqlConnection和MVVM简单介绍,有代码不明白的找锐英源软件。
在本文中,我想解释更多关于模型-视图-视图模型 (MVVM) 设计模式、为什么必须使用 MVVM 以及如何使用 MVVM 设计模式与 SQL Server 一起工作。
MVVM 模式包括三个关键部分:
ViewModel 充当View 和 Model 之间的接口。它提供View和模型数据之间的数据绑定, 并使用命令处理所有 UI 操作。
将View 其控件值绑定到ViewModel属性,这反过来又会公开Model 对象中包含的数据。
在传统的 UI 开发中 - 开发人员过去常常创建一个View,方式是使用窗口或用户控件或页面来创建,然后在后面代码中编写所有逻辑代码(事件处理、初始化和数据模型等),因此他们基本上是将代码作为视图定义类本身。这种方法增加了View 类,并在我的 UI 和数据绑定逻辑和业务操作之间创建了非常强的依赖关系。在这种情况下,没有两个开发人员可以同时在同一个视图上工作,而且一个开发人员的更改可能会破坏另一个代码。所以一切都在一个地方对于可维护性、可扩展性和可测试性来说总是一个坏主意。所以如果你看大局,你会感觉到所有这些问题都存在,因为以下几项之间存在非常紧密的耦合:
在 MVVM 中,Glue 代码是 View Model。因此,它基本上侧重于关注点分离,以使应用程序结构的实现更易于创建和维护。
创建一个新类并添加以下代码以创建委托命令:
public class DelegateCommand : ICommand
{
private readonly Action _execute;
private readonly Func<bool> _canExecute;
public DelegateCommand(Action execute)
: this(execute, () => true)
{
_execute = execute;
}
public DelegateCommand(Action execute, Func<bool> canExecute)
{
_execute = execute;
_canExecute = canExecute;
}
public void Execute(object parameter)
{
_execute();
}
public bool CanExecute(object parameter)
{
return _canExecute();
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
}
命令为视图提供了一种机制来更新 MVVM 架构中的模型。命令提供了一种在元素树中搜索命令处理程序的方法。该ICommand接口在命名空间内定义System.Windows.Input。它有两个方法和一个事件。
public bool CanExecute(object parameter) public void Execute(object parameter) public event EventHandler CanExecuteChanged
Execute 方法仅在CanExecute返回时调用true。如果CanExecute方法返回false,则绑定控件会自动禁用。
为了知道CanExecute值监听CanExecuteChanged事件,这可能会根据传递的参数而有所不同。
CanExecuteChanged通知绑定到的任何命令源(如 Button等)返回的值已更改。命令源关心这一点,因为它们通常需要相应地更新其状态(例如,如果返回, a将禁用自身)。CheckBoxICommandCanExecuteButtonCanExecute()false
CommandManager.RequerySuggested每当CommandManager认为某些事情发生了变化,会影响命令的执行能力时,就会引发该事件。这可能是焦点的改变。
public event EventHandler CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } }
创建一个新类并添加以下代码以创建一个ViewModel:
public class CreateEmployeeViewModel : INotifyPropertyChanged { private string _id; private string _firstName; private string _address; public CreateEmployeeViewModel() { SaveCommand = new DelegateCommand(Save, () => CanSave); } public string ID { get { return _id; } set { _id = value; NotifyOfPropertyChange("ID"); } } public string FirstName { get { return _firstName; } set { _firstName = value; NotifyOfPropertyChange("FirstName"); } } public string Address { get { return _address; } set { _address = value; NotifyOfPropertyChange("Address"); } } public ICommand SaveCommand { get; private set; } public bool CanSave { get { return !string.IsNullOrEmpty(ID) && !string.IsNullOrEmpty(FirstName); } } string connectionString = @"Data Source=RAVINDRA\MSSQLSERVERS;Initial Catalog=CrudMethod;Integrated Security=SSPI;"; public void Save() { SqlConnection con = new SqlConnection(connectionString); SqlCommand cmd = con.CreateCommand(); cmd.CommandText = "INSERT INTO Users(ID,FirstName,Address)VALUES(@ID,@FirstName,@Address)"; cmd.Parameters.AddWithValue("@ID", ID); cmd.Parameters.AddWithValue("@FirstName", FirstName); cmd.Parameters.AddWithValue("@Address", Address); try { con.Open(); cmd.ExecuteNonQuery(); } catch (SqlException ex) { throw ex; } finally { con.Close(); } MessageBox.Show("Data Saved Successfully."); }
该INotifyPropertyChanged接口用于通知客户端,通常绑定客户端属性值已更改。
例如,考虑一个Person 具有名为 的属性的对象FirstName。为了提供通用的属性更改通知,该Person类型实现了INotifyPropertyChanged接口并在更改时引发PropertyChanged事件FirstName。
要在绑定客户端和数据源之间的绑定中发生更改通知,您的绑定类型应该:
不要两者都做。
在MainWindow.xaml.cs中,添加以下代码以初始化ViewModel 类并将其包装ViewModel 到View usingDataContext属性中。
DataContext = new CreateEmployeeViewModel();
在MainWindow.xaml中添加以下代码:
<Window x:Class="WpfTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Helloworld" Height="350" Width="525">
<Grid>
<Button x:Name="btnSave"
HorizontalAlignment="Left"
TabIndex="100"
Content="Save"
Width="100"
Height="30"
Margin="100,0,100,0"
Command="{Binding Path= SaveCommand}" />
<TextBox Height="23"
HorizontalAlignment="Left" Margin="114,26,0,0"
Name="txtID" VerticalAlignment="Top"
Width="120" Text="{Binding ID}"/>
<TextBox Height="23"
HorizontalAlignment="Left" Margin="114,55,0,0"
Name="txFirstName" VerticalAlignment="Top"
Width="120" Text="{Binding FirstName }" />
<TextBox Height="23"
HorizontalAlignment="Left" Margin="114,84,0,0"
Name="txtAddress" VerticalAlignment="Top"
Width="120" Text="{Binding Address}" />
<Label Content="ID:" Height="28"
HorizontalAlignment="Left"
Margin="84,26,0,0" Name="label1"
VerticalAlignment="Top" />
<Label Content="First Name:" Height="28"
HorizontalAlignment="Left"
Margin="40,50,0,0" Name="label2"
VerticalAlignment="Top" />
<Label Content="Address:" Height="28"
HorizontalAlignment="Left"
Margin="53,75,0,0" Name="label3"
VerticalAlignment="Top" />
</Grid>
</Window>
注意:请查看我们绑定到SaveCommand上的 Button Command 属性,当单击按钮时,此SaveCommand以ICommand形式进行通信。