首先MVVM设计模式的结构,

Views: 由Window/Page/UserControl等构成,通过DataBinding与ViewModels建立关联;

ViewModels:由一组命令,可以绑定的属性,操作逻辑构成;因为View与ViewModel进行了解耦,我们可以对ViewModel进行Unit Test;

Models:可以是实体对象或者Web服务;

下面通过一个简单的例子,来介绍一些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 = ,
ZoomOut = ,
Normal =
} 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 = ;
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();
}

程序运行效果如下:

到此为止,这个简单的示例就算完成了。点击这里下载代码。

感谢您的阅读。

最新文章

  1. Java Se:自定义ClassLoader
  2. ACM/ICPC 之 DP进阶(51Nod-1371(填数字))
  3. 合唱队形2(洛谷U5874)
  4. c/c++ 指针理解(1)
  5. 字符编码 and cpp
  6. Word或者Excel中怎么把 &quot;空格&quot; 替换成 &quot;换行 &quot;
  7. JS之延迟处理
  8. debian完整部署 Nginx + uWSGI + Django
  9. image sensor 积分时间
  10. 20151214 jquery插件代码备份
  11. 【HDOJ】4704 Sum
  12. hdu4717 The Moving Points(二分做法)
  13. 2014年蓝桥杯预选赛 C/C++ 本科A组试题--切面条
  14. dva框架使用mock.js模拟数据 + fetch请求数据
  15. 【Java资源免费分享,网盘自己拿】
  16. Java_Object_Date_System等常用类
  17. Linux 系统管理
  18. select2 javascript控件 如何设置指定的值
  19. Java 多线程并发编程面试笔录一览
  20. PHP代码审计笔记--命令执行漏洞

热门文章

  1. MYSQL 的错误Incorrect information in file: &#39;.\test\stuff.frm
  2. 向SqlServer数据库插入数据
  3. POJ 3026(BFS+prim)
  4. CentOS 7部署flume
  5. java -jar jenkins.war
  6. Qt 对话框显示控制按钮
  7. 设置UISegmentedControl的字体大小和颜色
  8. hdu 1014.Uniform Generator 解题报告
  9. 【python】入门学习(六)
  10. 【编程题目】一个整数数组,长度为 n,将其分为 m 份,使各份的和相等,求 m 的最大值★★ (自己没有做出来!!)