MVVM模式介绍
MVVM是(Model,View,ViewModel)这种模式就是使用ViewModel来降低View和Model的耦合。换个方式就是降低“界面”和“逻辑”的耦合,理想情况下界面和逻辑的完全分离的,像单方面更改界面时不需要对逻辑代码的改动,同样逻辑代码更改也不需要更改界面。同一个ViewModel可以使用完全不用view进行展示,同一个view也可以使用的viewmodel以提供不同的操作。
Model
Model相当于Class,是对现实中事物的抽象,开发过程中涉及到的事物都可以抽象为Model,例如客户,姓名,编号,电话,住址等属性也对应了class中的property,客户下订单,付款等行为对应了class中的方法。
View
view就是界面
ViewModel
viewmodel就是对view的抽象,显示的数据对应着ViewModel中Property,执行的命令对应着ViewModel中的Command。
WPF中MVVM的解耦方式
在wpf的mvvm模式中,view和viewmodel之间数据和命令的关联都是通过绑定实现的,绑定后View和ViewModel并不产生直接依赖。具体就是View中出现数据变化时会尝试修改绑定的目标。同样View执行命令时也会去寻找绑定的Command并执行。反过来,viewmodel在Property发生改变时会发个通知说“名字叫XX的property改变了,某些view中谁绑定了XX也要跟着变”,至于有没有View收到是不是做出变化也不关心。ViewModel中的Command脱离View就更简单了,因为Command在执行过程中操作数据时,根本不需要操作View中的数据,只需要操作ViewModel中Property就可以了,Property的变化通过绑定就可以反映到View上。这样测试Command时也不需要View的参与。
MVVMLigth模式简单的例子
在nuget包中下载mvvmligth
它会自动生成有ViewModel模式
**快捷键生成 例如propvm是mvvm模式中特殊的属性… **
导入文件
App.xmal自动生成一下内容
Slider,TextBox控件之间的绑定
前台mianwindow.xmal
<StackPanel>
<Slider Margin="10"
Maximum="100"
Minimum="0"
Value="{Binding MyProperty}" />
<Slider Margin="10"
Maximum="100"
Minimum="0"
Value="{Binding MyProperty}" />
<ProgressBar Margin="10" Value="{Binding MyProperty}" />
<ProgressBar Margin="10" Value="{Binding MyProperty}" />
<TextBox Margin="10" Text="{Binding Path=MyProperty, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
<TextBlock Margin="10" Text="{Binding Path=MyProperty}" />
</StackPanel>
MainViewModel.cs
快捷键:propvm+tab两下
public class MainViewModel : ViewModelBase
{
public MainViewModel()
{
//计时器
Timer timer = new Timer();
timer.Interval = 2000;
timer.Elapsed += Timer_Elapsed;
timer.Start();
}
private void Timer_Elapsed(object sender, ElapsedEventArgs e) {
MyProperty++;
}
private double myVar=10;
public double MyProperty {
get {
return myVar;
}
set {
Set(ref myVar, value);
}
}
private int nums = 0;
private ObservableCollection<int> num = new ObservableCollection<int>();
public ObservableCollection<int> Nums {
get {
return num;
}
set {
Set(ref num, value);
}
}
private RelayCommand addCommand = null;
public RelayCommand Addcommand {
get {
return addCommand ?? new RelayCommand(() => {
nums++;
Nums.Add(nums);
});
}
}
最后的效果
WPF UpdateSourceTrigger属性
TextBox中的变化并不是立即传递到源,而是在TextBox失去焦点后,源才更新。这种表现由绑定中的UpdateSourceTrigger属性来控制。它的默认值是Default,源会根据你绑定的属性来更新。写这篇文章的时候,除了Text属性之外的所有属性,源会随属性的改变而立即更新。Text属性不一样,它只有在目标元素失焦后才更新。
- PropertyChanged,一旦绑定的属性值改变,源会立即更新。
- LostFocus,对于Text绑定来说其实就是一个默认值。也就是说一旦目标控件失去焦点,源就会被更新。
- Explicit,源不会更新除非你手动来操作
WPF Binding(四种模式) - TwoWay:导致对源属性或目标属性的更改可自动更新对方
- OneWay:当绑定源(源)更改时,更新绑定目标(目标)属性。如果要绑定的控件为隐式只读控件,则适用此绑定类型。
- OneTime:当应用程序启动或数据上下文更改时,更新绑定目标。此绑定类型适用于以下情况:使用当前状态的快照适合使用的或数据状态实际为静态的数据。
- OneWayToSource:当目标属性更改时更新源属性。
- Default:使用绑定目标的默认 Mode 值。每个依赖项属性的默认值都不同。