今天解决的是关于Model与数据界面绑定的问题。
在编写一些程序的时候难免遇到需要动态绑定一些数据进一个ListView或者GridView,而这些东西在MVVM中属于View的范畴——View必定是与ViewModel通信来获得Model的,所以在xaml文件中绑定的资源必定存在于ViewModel中,而ViewModel与View绑定全靠ViewModelLocator,名字就展示了他的功能,并且ViewModelLocator是个单独的文件,示例:
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Ioc;
using Microsoft.Practices.ServiceLocation;
namespace App.ViewModel
{
/// <summary>
/// This class contains static references to all the view models in the
/// application and provides an entry point for the bindings.
/// </summary>
public class ViewModelLocator
{
/// <summary>
/// Initializes a new instance of the ViewModelLocator class.
/// </summary>
public ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<AppViewModel>();
}
public AppViewModel App
{
get
{
return ServiceLocator.Current.GetInstance<AppViewModel>();
}
}
public static void Cleanup()
{
// TODO Clear the ViewModels
}
}
}
在xaml文件中与相应的控件绑定DataContext来达到定位的目的,示例:
<Window x:Class="App.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:MapEditorControl"
xmlns:vm="clr-namespace:MapEditorControl.ViewModel"
mc:Ignorable="d"
d:DesignHeight="609" d:DesignWidth="263">
<Window.Resources>
<vm:ViewModelLocator x:Key="Locator"/>
</Window.Resources>
<TabControl DataContext="{Binding Source={StaticResource Locator}, Path=App}">
<!-- TabItem...-->
</TabControl>
</Window>
这样就解决了View与ViewModel绑定的文件,现在View可以绑定任何ViewModel暴露出来的DP,十分方便。
然而我们在实际运用之中经常要把一个动态变化的集合绑定到ListView或者GridView等等列表性质的东西上,这个时候ViewModel里的单个依赖属性就显得无法满足我们的需求,这个时候我们就需要C#的ObservableCollection来将需要绑定的对象打包,其中
public ObservableCollection<T> Example;
这里需要注意的是ObservableCollection只接受类对象,所以需要把要用的数据包装成一个类,再以这个类新建一个ObservableCollection的示例,这样便可以绑定到View的ItemsSource上,其中以ListView为例:
<TabControl TabStripPlacement="Top"
DataContext="{Binding Source={StaticResource Locator}, Path=App}">
<TabItem Header="Test" Width="53">
<ListView ItemsSource="{Binding DataSection}">
<ListView.ItemTemplate>
<DataTemplate>
<RadioButton Content="{Binding Data}"/>
</DataTemplate>
</ListView.ItemTemplate>
<!--DynamicResource -->
</ListView>
</TabItem>
</TabControl>
DataSection便是包装好的类对象,Data是类中的数据,这里需要注意的是ItemTemplate与DataTemplate的使用,详细用法可以参考《深入浅出WPF》的模板一章。
这样View就与ViewModel的数据实现了绑定。ViewModel再与Model绑定就可以完成这个数据显示的问题。
欢迎指正。