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

    程序运行效果如下:

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

    感谢您的阅读。

  • 相关阅读:
    Learn Prolog Now 翻译
    Learn Prolog Now 翻译
    Learn Prolog Now 翻译
    Learn Prolog Now 翻译
    Learn Prolog Now 翻译
    Learn Prolog Now 翻译
    Learn Prolog Now 翻译
    Learn Prolog Now 翻译
    Learn Prolog Now 翻译
    Learn Prolog Now 翻译
  • 原文地址:https://www.cnblogs.com/wangchaoyuana/p/7523570.html
Copyright © 2011-2022 走看看