在MvvmLight中View和ViewModel的绑定
本文会介绍在MvvmLight框架下几种情况下的页面绑定方法,分别使用了{x:Bind}, {Binding};在一个View对应多个ViewModel情况下两种绑定方法,以及混合两种方式的绑定方法。
准备工作
ViewModel
为了完成以下内容,ViewModel需要准备两个类
MainPageViewModel
public class MainViewModel : ViewModelBase
{
private string _Title="MainPage";
public string Title { get { return _Title; } set { Set(ref _Title, value); } }
}
PageTwoViewModel
public class PageTwoViewModel : ViewModelBase
{
private string _Title="PageTwo";
public string Title { get { return _Title; } set { Set(ref _Title, value); } }
}
ViewModelLocator
MvvmLight自带
public class ViewModelLocator
{
/// <summary>
/// Initializes a new instance of the ViewModelLocator class.
/// </summary>
public ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
////if (ViewModelBase.IsInDesignModeStatic)
////{
//// // Create design time view services and models
//// SimpleIoc.Default.Register<IDataService, DesignDataService>();
////}
////else
////{
//// // Create run time view services and models
//// SimpleIoc.Default.Register<IDataService, DataService>();
////}
SimpleIoc.Default.Register<MainPageViewModel>();
SimpleIoc.Default.Register<PageTwoViewModel>();
}
public MainPageViewModel Main
{
get
{
return ServiceLocator.Current.GetInstance<MainPageViewModel>();
}
}
public PageTwoViewModel PageTwo
{
get { return ServiceLocator.Current.GetInstance<PageTwoViewModel>(); }
}
public static void Cleanup()
{
// TODO Clear the ViewModels
}
}
一个View对应一个ViewModel
这种情况是最为常见的情况,实现方法比较简单
使用x:Bind
因为使用x:Bind是找自己同空间下的属性,所以要在后台代码里写点东西,把ViewModel引入进来,微软推荐尽量使用x:Bind代替Binding
Code-Behind中代码(MainPage.xaml.cs)
public MainPageViewModel Model{ get; set;} = new MainPageViewModel();
Xaml
使用了x:Bind就不需要定义Page.DataContext,注意默认x:Bind的绑定模式(Mode)是OneTime,根据需要修改Mode
<TextBlock Grid.Row="0" Text="{x:Bind Model.Title,Mode=OneWay}"/>
使用Binding
传统使用方法
Xaml
定义DataContext,Path属性为ViewModelLocator中定义的MainPageViewModel类型的属性名
<Page.DataContext>
<Binding Path="Main" Source="{StaticResource Locator}"/>
</Page.DataContext>
...
...
...
<TextBlock Text="{Binding Title}"/>
上面那个{StaticResource Locator}
在App.xaml中定义
<Application.Resources>
<ResourceDictionary>
<vms:ViewModelLocator x:Key="Locator" />
</ResourceDictionary>
</Application.Resources>
混合使用
Code-Behind中代码(MainPage.xaml.cs)
public MainPageViewModel Model
{
get
{
return (MainPageViewModel )DataContext;
}
}
Xaml
<Page.DataContext>
<Binding Path="Main" Source="{StaticResource Locator}"/>
</Page.DataContext>
...
...
...
<TextBlock Text="{Binding Title}"/>
<TextBlock Text="{x:Bind Model.Title}"/>
一个页面View对应多个ViewModel
这种情况不多见,但是有的时候也需要用到
使用x:Bind
直接定义多个属性即可
Code-Behind中代码(MainPage.xaml.cs)
public MainPageViewModel Model{ get; set;} = new MainPageViewModel();
public PageTwoViewModel PageTwo{ get; set;} = new PageTwoViewModel();
Xaml
<TextBlock Grid.Row="0" Text="{x:Bind Model.Title,Mode=OneWay}"/>
<TextBlock Grid.Row="1" Text="{x:Bind PageTwo.Title,Mode=OneWay}"/>
使用Binding
Xaml
注意DataContext配置中去掉Path路径
<Page.DataContext>
<Binding Source="{StaticResource Locator}"/>
</Page.DataContext>
...
...
...
<TextBlock Grid.Row="0" Text="{Binding Main.Title}"/>
<TextBlock Grid.Row="1" Text="{Binding PageTwo.Title}"/>
混合使用
Code-Behind中代码(MainPage.xaml.cs)
public ViewModelLocator Model
{
get
{
return (ViewModelLocator)DataContext;
}
}
直接返回ViewModelLocator对象
Xaml
<Page.DataContext>
<Binding Source="{StaticResource Locator}"/>
</Page.DataContext>
...
...
...
<TextBlock Text="{Binding Main.Title}"/>
<TextBlock Text="{x:Bind Model.PageTwo.Title}"/>