欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

WPF MVVM示例讲解

程序员文章站 2023-12-10 23:40:34
在没给大家讲解wpf mwm示例之前先给大家简单说下mvvm理论知识: wpf技术的主要特点是数据驱动ui,所以在使用wpf技术开发的过程中是以数据为核心的,wpf提供了...

在没给大家讲解wpf mwm示例之前先给大家简单说下mvvm理论知识:

wpf技术的主要特点是数据驱动ui,所以在使用wpf技术开发的过程中是以数据为核心的,wpf提供了数据绑定机制,当数据发生变化时,wpf会自动发出通知去更新ui。

  我们使用模式,一般是想达到高内聚低耦合。在wpf开发中,经典的编程模式是mvvm,是为wpf量身定做的模式,该模式充分利用了wpf的数据绑定机制,最大限度地降低了xmal文件和cs文件的耦合度,也就是ui显示和逻辑代码的耦合度,如需要更换界面时,逻辑代码修改很少,甚至不用修改。与winform开发相比,我们一般在后置代码中会使用控件的名字来操作控件的属性来更新ui,而在wpf中通常是通过数据绑定来更新ui;在响应用户操作上,winform是通过控件的事件来处理,而wpf可以使用命令绑定的方式来处理,耦合度将降低。

首先mvvm设计模式的结构

WPF MVVM示例讲解

views: 由window/page/usercontrol等构成,通过databinding与viewmodels建立关联;
viewmodels:由一组命令,可以绑定的属性,操作逻辑构成;因为view与viewmodel进行了解耦,我们可以对viewmodel进行unit test;
models:可以是实体对象或者web服务;

下面通过一个简单的例子,来介绍一些wpf mvvm模式。示例将展示一个图片浏览器,打开图片,放大/缩小图片大小。首先项目结构:

WPF MVVM示例讲解

ui:

   

 <grid>
  <dockpanel>
   <menu dockpanel.dock="top">
    <menu>
     <menuitem header="_open" command="{binding openfilecommand}"/>
    </menu>
    <menu>
     <menuitem header="_zoomin" command="{binding zoomcommand}" commandparameter="zoomin"/>
    </menu>
    <menu>
     <menuitem header="_zoomout" command="{binding zoomcommand}" commandparameter="zoomout"/>
    </menu>
    <menu>
     <menuitem header="_normal" command="{binding zoomcommand}" commandparameter="normal"/>
    </menu>
   </menu>
   <scrollviewer>
    <image source="{binding imagepath}" stretch="none">
     <image.layouttransform>
      <scaletransform scalex="{binding zoom}" scaley="{binding zoom}"/>
     </image.layouttransform>
    </image>
   </scrollviewer>
  </dockpanel>
 </grid>

viewmodelbase(用来实现修改通知):

  

 public class viewmodelbase : inotifypropertychanged
 {
  public event propertychangedeventhandler propertychanged;
  protected virtual void onpropertychanged(string propname)
  {
   if(propertychanged!=null)
   {
    propertychanged(this, new propertychangedeventargs(propname));
   }
  }
 }

openfilecommand:

public class openfilecommand : icommand
 {
  private mainviewmodel _data;
  public openfilecommand(mainviewmodel data)
  {
   _data = data;
  }
  public event eventhandler canexecutechanged;
  public bool canexecute(object parameter)
  {
   return true;
  }
  public void execute(object parameter)
  {
   openfiledialog dialog = new openfiledialog() { filter = "image files|*.jpg;*.png;*.bmp;*.gif" };
   if(dialog.showdialog().getvalueordefault())
   {
    _data.imagepath = dialog.filename;
   }
  }

zoomcommand:

   

 public enum zoomtype
 {
  zoomin = 0,
  zoomout = 1,
  normal = 2
 }
 public class zoomcommand : icommand
 {
  private mainviewmodel _data;
  public zoomcommand(mainviewmodel data)
  {
   _data = data;
  }
  public event eventhandler canexecutechanged
  {
   add { commandmanager.requerysuggested += value; }
   remove { commandmanager.requerysuggested -= value; }
  }
  public bool canexecute(object parameter)
  {
   return _data.imagepath != null;
  }
  public void execute(object parameter)
  {
   zoomtype type = (zoomtype)enum.parse(typeof(zoomtype), (string)parameter, true);
   switch(type)
   {
    case zoomtype.normal:
     _data.zoom = 1;
     break;
    case zoomtype.zoomin:
     _data.zoom *= 1.2;
     break;
    case zoomtype.zoomout:
     _data.zoom /= 1.2;
     break;
   }
  }
 }

mainviewmodel:

public class mainviewmodel : viewmodelbase
 {
  private string _imagepath;
  public string imagepath
  {
   get
   {
    return _imagepath;
   }
   set
   {
    if (_imagepath != value)
    {
     _imagepath = value;
     onpropertychanged("imagepath");
    }
   }
  }
  private double _zoom = 1.0;
  public double zoom
  {
   get
   {
    return _zoom;
   }
   set
   {
    if(_zoom != value)
    {
     _zoom = value;
     onpropertychanged("zoom");
    }
   }
  }
  private icommand _openfilecommand;
  public icommand openfilecommand
  {
   get { return _openfilecommand; }
  }
  private zoomcommand _zoomcommand;
  public zoomcommand zoomcommand
  {
   get { return _zoomcommand; }
  }
  public mainviewmodel()
  {
   _openfilecommand = new openfilecommand(this);
   _zoomcommand = new zoomcommand(this);
  }
 }

下一步我们要做的是将mainviewmodel绑定到mainwindow上,我们可以通过下面两种方式绑定:
1. 直接在mainwindow的code behind中进行绑定:
       

 public mainwindow()
  {
   initializecomponent();
   datacontext = new mainviewmodel();
  }

2. 在app.xaml后台代码中绑定(将app.xaml中startupuri="mainwindow.xaml"删除掉):

  public app()
  {
   mainwindow window = new mainwindow();
   window.datacontext = new mainviewmodel();
   window.show();
  }

运行效果图如下:

WPF MVVM示例讲解

以上就是针对wpf mvvm示例讲解的全部内容,并附有效果图,看着还不错吧,希望大家能够喜欢,欢迎提出宝贵意见。