1.Xaml标记实现和代码隐藏
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Slider HorizontalAlignment="Left" Margin="106,38,0,0" VerticalAlignment="Top" Width="621" Value="{Binding Input1}"/>
<Slider HorizontalAlignment="Left" Margin="106,83,0,0" VerticalAlignment="Top" Width="621" Value="{Binding Input2}"/>
<Slider HorizontalAlignment="Left" Margin="106,132,0,0" VerticalAlignment="Top" Width="621" Value="{Binding Result}"/>
<Button Content="Button" HorizontalAlignment="Left" Margin="355,200,0,0" VerticalAlignment="Top" Width="99" Height="29" Command="{Binding AddCommand}"/>
</Grid>
</Window>
更新的标记定义 xmlns:x 命名空间,并将其映射到为代码隐藏类型添加支持的架构。 x:Class 特性用于将代码隐藏类与此特定 XAML 标记相关联。 考虑此特性在 <Window> 元素上声明,代码隐藏类必须从 Window 类继承。
namespace WpfApp1
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
// InitializeComponent call is required to merge the UI
// that is defined in markup with this class, including
// setting properties and registering event handlers
InitializeComponent();
this.DataContext = new MainWindowViewModel();
}
}
}
从代码隐藏类的构造函数调用 InitializeComponent,以将标记中定义的 UI 与代码隐藏类合并在一起。x:Class 和 InitializeComponent 的组合可确保在创建实现时正确地对其进行初始化。
若要使 XAML 标记文件和代码隐藏文件配合工作,需要满足以下要求:
-
在标记中,
Window元素必须包含x:Class属性。 生成应用程序时,标记文件中存在x:Class会使 Microsoft 生成引擎 (MSBuild) 生成派生自 Window 的partial类,其名称由x:Class属性指定。 这要求为 XAML 架构 (xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml") 添加 XAML 命名空间声明。 生成的partial类实现InitializeComponent方法,注册事件和设置在标记中实现的属性时将调用此方法。 -
在代码隐藏中,类必须是
partial类、名称必须是标记中x:Class属性指定的相同名称,并且它必须派生自 Window。 这样,代码隐藏文件就与应用程序生成时为标记文件生成的partial类相关联 -
在代码隐藏中,Window 类必须实现调用
InitializeComponent方法的构造函数。InitializeComponent由标记文件已生成的partial类实现,用以注册事件并设置标记中定义的属性。
2.MVVM架构原理
基于数据绑定和命令模式实现:
- 数据绑定:视图和视图模型之间通过数据绑定来实现交互。当视图模型中的数据发生变化时,视图会自动更新相应的内容,从而实现了视图和视图模型之间的数据同步。
- 命令模式:视图和视图模型之间通过命令模式来实现交互。视图中的用户交互事件会被转换为命令,然后传递给视图模型进行处理。
MVVM架构的核心在于将视图和模型完全解耦,视图只负责渲染用户界面,而视图模型负责处理业务逻辑和数据操作。视图和视图模型之间通过数据绑定和命令模式进行交互,从而实现了解耦和职责分离。

实例场景:两个输入值,计算他们的和,得到一个结果
ViewModel基类:
namespace WpfApp1.ViewModels
{
class NotificationObject : INotifyPropertyChanged
{
//ViewModel的某个属性借助Binding关联到View上的控件属性
//Binding会侦听该事件的发生(属性值更改时发生),并把改变后的属性值发送到界面
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName)
{
if(this.PropertyChanged!=null)
{
//触发属性更改事件
this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
ViewModel类:
namespace WpfApp1.ViewModels
{
class MainWindowViewModel:NotificationObject
{
private double input1;
public double Input1
{
get { return input1; }
set{
input1 = value;
this.RaisePropertyChanged("Input1");
}
}
private double input2;
public double Input2
{
get { return input2; }
set
{
input2 = value;
this.RaisePropertyChanged("Input2");
}
}
private double result;
public double Result
{
get { return result; }
set
{
result = value;
this.RaisePropertyChanged("Result");
}
}
public DelegateCommand AddCommand { get; set; }
private void Add(object paramater)
{
//属性值改变,触发set,通知binding
this.Result = Input1 + Input2;
}
public MainWindowViewModel()
{
//初始化命令
this.AddCommand=new DelegateCommand ();
this.AddCommand.ExcuteAction = new Action<object>(Add);
}
}
}
DelegateCommand类:
namespace WpfApp1.Command
{
class DelegateCommand : ICommand
{
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
if (this.CanExcuteFunc == null)
return true;
return this.CanExcuteFunc(parameter);
}
//定义调用此命令时要调用的方法
public void Execute(object parameter)
{
if (ExcuteAction == null)
return;
//执行这个委托传递的方法
this.ExcuteAction(parameter);
}
public Action<object> ExcuteAction { get; set; }
public Func<object, bool> CanExcuteFunc { get; set; }
}
}