星星之火

燎原之势不可挡
随笔 - 128, 文章 - 3, 评论 - 377, 阅读 - 65万
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

MVVM模型新手入门体验

Posted on   星星之火116  阅读(410)  评论(0编辑  收藏  举报

MVVM(Model-View-ViewModel)模型浅析

MVVM模型类似于ASP.NET中的MVC模型

与之不同的是MVC模型实现了Model层和View层的分离,但是View的显示依赖于Model曾和Cotroller的控制

而MVVM模型实现了Model层和View层的完全隔离,

View和ViewModel之间主要通过Databinding来显示ViewModel数据,

同时View可以通知ViewModel数据的变化(设置Binding Mode);

用户操作通过绑定对应Command以通知ViewModel进行逻辑处理,

ViewModel通过消息更新View的显示。

下边通过一个简单的Demo的关键步骤解析下MVVM模型的用法,

一、创建好WP7应用程序项目,分别添加两个文件夹Model和ViewModel

在Model文件夹中创建实体类,这点 有点类似于MVC中Model层,形成用户操作数据数据和类的映射,

例如:

using System; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes;
namespace MVVMModel.Model {     public class People     {         public string Name         {             get;             set;         }         public string Address         {             get;             set;         }         public string Telephone         {             get;             set;         }
        public string Picture         {             get;             set;         }     } }

同时再在Model文件夹中添加PeopleService类,通过创建一些方法方便获取People的数据

如下:

using System; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using System.Collections.ObjectModel; using System.Collections.Generic; namespace MVVMModel.Model {     public class PeopleService     {

      ///获取源数据         public List<People> GetAllPeople()         {             List<People> people = new List<People>()             {                 new People(){ Name="Olive", Address="北京", Telephone="1111111111", Picture="/Images/不甘心.jpg"},                 new People(){ Name="Yao", Address="北京", Telephone="2222222222", Picture="/Images/纯洁.jpg"},                 new People(){ Name="Momo", Address="北京", Telephone="333333333", Picture="/Images/多拉A梦.jpg"},                 new People(){ Name="Xue", Address="北京", Telephone="4444444444", Picture="/Images/额.jpg"}             };             return people;         }

 

然后需要在ViewModel文件夹中添加MainViewModel类(核心类),作为Model层和View层交互的桥梁

如下:

public MainViewModel()         {             appName = "People Hub";             AppTitle = "Welcome To People Hub";             Peoples = new ObservableCollection<People>(peopleService.GetAllPeople());                 }         private PeopleService peopleService = new PeopleService();
        public event PropertyChangedEventHandler PropertyChanged;         private string appName;         private string appTitle;         public string AppName         {             get             {                 return appName;             }             set             {                 if (appName == value)                     return;                 appName=value;                 OnPropertyChanged("AppName");             }         }
        public string AppTitle         {             get             {                 return appTitle;             }             set             {                 if (appTitle == value)                     return;                 appTitle = value;                 OnPropertyChanged("AppTitle");             }         }
        public ObservableCollection<People> people;         public ObservableCollection<People> Peoples         {             get             {                 return people;             }             set             {                 if (people == value)                     return;                 people = value;                 OnPropertyChanged("Peoples");             }         }        public void OnPropertyChanged(string propertyChangedName)        {            if (PropertyChanged != null)                PropertyChanged(this, new PropertyChangedEventArgs(propertyChangedName));        } 这是需要实现INotificatyChanged接口,在INotifyPropertyChanged接口在using System.ComponentModel命名空间下

这时就只需要在MainPage.xaml页进行绑定就可以了

首先引入命名空间:

  xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"     xmlns:mv="clr-namespace:MVVMModel.ViewModel"     mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"

然后在页面资源里声明MainViewModel为页面资源

<phone:PhoneApplicationPage.Resources>         <mv:MainViewModel x:Name="MainViewModel"></mv:MainViewModel>

。。。。。。

</phone:PhoneApplicationPage.Resources> 这时可能会提示你实例无法创建,只需要把项目生成一下就可以了,

然后就资源与相关控件绑定就可以,

 

<phone:PhoneApplicationPage.Resources>         <mv:MainViewModel x:Name="MainViewModel"></mv:MainViewModel>         <DataTemplate x:Name="PeopleTemplage"  >//为ListBoxItem项创建的模板             <StackPanel Orientation="Vertical">                 <TextBlock Text="{Binding Name}"/>                 <TextBlock Text="{Binding Address}"/>                 <TextBlock Text="{Binding Telephone}"/>                 <Image Source="{Binding Picture}" Width="200" Height="200" Stretch="Fill"/>             </StackPanel>         </DataTemplate>     </phone:PhoneApplicationPage.Resources>     <!--LayoutRoot 是包含所有页面内容的根网格-->     <Grid x:Name="LayoutRoot" Background="Transparent" DataContext="{StaticResource MainViewModel}">//将整个MainViewModel绑定到顶层容器Grid上         <Grid.RowDefinitions>             <RowDefinition Height="Auto"/>             <RowDefinition Height="*"/>         </Grid.RowDefinitions>

        <!--TitlePanel 包含应用程序的名称和页标题-->         <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">             <TextBlock x:Name="ApplicationTitle" Text="{Binding AppTitle}" Style="{StaticResource PhoneTextNormalStyle}"/>             <TextBlock x:Name="PageTitle" Text="{Binding AppName}" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>         </StackPanel>

        <!--ContentPanel - 在此处放置其他内容-->         <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">             <ListBox ItemsSource="{Binding Peoples}" ItemTemplate="{StaticResource PeopleTemplage}" Width="468" Height="270" Margin="6,6,-18,331"></ListBox>                     </Grid>     </Grid>

这样就可以实现数据的绑定了运行就可以看到效果了

如果需要实现用户的添加删除等其他的操作,则需要将控件和Command进行绑定,

这样需要创建新的类例如添加,则需创建IAddCommd类,该类需要实现ICommand接口

主要有以下几个函数:

private readonly MainViewModel mainViewModel;         public AddCommand(MainViewModel mainviewmodel)         {             mainViewModel = mainviewmodel;         }         public event EventHandler CanExecuteChanged;         public bool CanExecute(object parameter)         {             return true;         }   public event EventHandler CanExecuteChanged;         public bool CanExecute(object parameter)         public void Execute(object parameter)//在这里边写需要的操作代码         {             mainViewModel.AddPeople(mainViewModel.People);         }

同时在MainViewModel里添加属性AddCommand,

在前台界面部分将AddCommand属性绑定到控件的Command属性上

如下:

<Button Content="Save" Height="72" HorizontalAlignment="Left" Margin="10,545,0,0" Name="btnSave" Command="{Binding AddCommand}"                     VerticalAlignment="Top" Width="160" />

这样就可以实现用户的操作了,在运行之前要注意AddCommand属性的初始化:

如下:

public MainViewModel()         {             appName = "People Hub";             AppTitle = "Welcome To People Hub";             Peoples = new ObservableCollection<People>(peopleService.GetAllPeople());             AddCommand = new AddCommand(this);

}

 

总结:刚开始接触MVVM模型看了之后感觉跟MVC模式有些相似之处,最大的突破在于View层和Model层的完全隔离,使得View层和Model层相互之间不再依赖影响,极大的方便了美工做出用户体验较好的UI,更方便了编程人员和美工的分工合作,极大的促进了开发效率。

另关于绑定Comman部分,由于篇幅有限只写了几个关键的点,希望有需要的朋友留个邮箱给发源码。(学习中)

编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示