zoukankan      html  css  js  c++  java
  • WPF MVVM初体验

    首先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 = 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();
            }

    程序运行效果如下:

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

    感谢您的阅读。

  • 相关阅读:
    hdu 6702 ^&^ 位运算
    hdu 6709 Fishing Master 贪心
    hdu 6704 K-th occurrence 二分 ST表 后缀数组 主席树
    hdu 1423 Greatest Common Increasing Subsequence 最长公共上升子序列 LCIS
    hdu 5909 Tree Cutting FWT
    luogu P1588 丢失的牛 宽搜
    luogu P1003 铺地毯
    luogu P1104 生日
    luogu P1094 纪念品分组
    luogu P1093 奖学金
  • 原文地址:https://www.cnblogs.com/yang-fei/p/4701946.html
Copyright © 2011-2022 走看看