实用的MVVM:ImageView
最近在学习WPF,遇到一本入门好书,推荐给大家《Windows Presentation Foundation 4.5 Cookbook》
做项目首先要从MVVM开始,现在把他的Simple MVVM例子介绍给大家,感觉简单但很实用
1. App.xaml.cs中重载OnStartup
protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); var mainWindow = new MainWindow(); mainWindow.DataContext = new ImageData(); mainWindow.Show(); }
2. ViewModel的实现
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class ImageData:INotifyPropertyChanged { public ImageData() { _openImageFileCommand = new OpenImageFileCommand(this); _zoomCommand = new ZoomCommand(this); } public ICommand OpenImageFileCommand { get { return _openImageFileCommand; } } public ICommand ZoomCommand { get { return _zoomCommand; } } public string ImagePath { get { return _imagePath; } set { _imagePath = value; this.RaisePropertyChanged("ImagePath"); } } public double Zoom { get { return _zoom; } set { _zoom = value; this.RaisePropertyChanged("Zoom"); } } private void RaisePropertyChanged(string propertyName) { var handler = PropertyChanged; if (handler == null) return; handler(this, new PropertyChangedEventArgs(propertyName)); } public event PropertyChangedEventHandler PropertyChanged; private double _zoom = 1.0; private string _imagePath; private OpenImageFileCommand _openImageFileCommand; private ZoomCommand _zoomCommand; }
3. 下面看看View是怎么做的,除了Xaml加绑定,不再需要其它多余的代码了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:CH07.RoutedCommands" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="CH07.RoutedCommands.MainWindow" d:DataContext="{d:DesignInstance Type=local:ImageData, IsDesignTimeCreatable=True}" Title="Image Viewer" Height="350" Width="525"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition /> </Grid.RowDefinitions> <ToolBar FontSize="14"> <Button Content="Open..." Command="{Binding OpenImageFileCommand}" Margin="6"/> <Button Content="Zoom In" Command="{Binding ZoomCommand}" CommandParameter="ZoomIn" Margin="6"/> <Button Content="Zoom Out" Command="{Binding ZoomCommand}" CommandParameter="ZoomOut" Margin="6"/> <Button Content="Normal" Command="{Binding ZoomCommand}" CommandParameter="ZoomNormal" Margin="6"/> </ToolBar> <ScrollViewer Grid.Row="1" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"> <Image Source="{Binding ImagePath}" Stretch="None"> <Image.LayoutTransform> <ScaleTransform ScaleX="{Binding Zoom}" ScaleY="{Binding Zoom}" /> </Image.LayoutTransform> </Image> </ScrollViewer> </Grid> </Window>
4. 还有ViewModel里的Command
ZoomCommand里的代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class ZoomCommand:ICommand { public ZoomCommand(ImageData data) { _data = data; } public bool CanExecute(object parameter) { if (_data.ImagePath == null) return false; return _data.ImagePath.IsPicture(); } public event EventHandler CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } } private ImageData _data; public void Execute(object parameter) { var zoomType = (ZoomType)Enum.Parse(typeof(ZoomType), (string)parameter, true); switch (zoomType) { case ZoomType.ZoomIn: _data.Zoom *= 1.2; break; case ZoomType.ZoomOut: _data.Zoom /= 1.2; break; case ZoomType.ZoomNormal: _data.Zoom = 1.0; break; default: break; } } } enum ZoomType { ZoomIn, ZoomOut, ZoomNormal }
下面是OpenImageFileCommand
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class OpenImageFileCommand:ICommand { public OpenImageFileCommand(ImageData data) { _data = data; } public bool CanExecute(object parameter) { return true; } public event EventHandler CanExecuteChanged; private ImageData _data; public void Execute(object parameter) { var dlg = new OpenFileDialog { Filter = "图形 文件|*.jpg;*.png;*.bmp;*.gif" }; if (dlg.ShowDialog()==true) { _data.ImagePath = dlg.FileName; } } }
5. 其它
判断打开的文件类型
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public static bool IsPicture(this string filePath) { try { FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read); BinaryReader reader = new BinaryReader(fs); string fileClass; byte buffer; byte[] b = new byte[2]; buffer = reader.ReadByte(); b[0] = buffer; fileClass = buffer.ToString(); buffer = reader.ReadByte(); b[1] = buffer; fileClass += buffer.ToString(); reader.Close(); fs.Close(); ////255216是jpg;7173是gif;6677是BMP,13780是PNG;7790是exe,8297是rar return ((fileClass == "255216" || fileClass == "7173" || fileClass == "6677" || fileClass == "13780") ? true : false); } catch { return false; } }