wpf快速了解(3)MVVM模式,行为绑定

勇哥注:

此系列贴子服务于C# winform开发工程师,帮助他们快速了解wpf技术,节省大家的学习成本。

因此,这个系列不是讲给初学者听的。

我们知道winform是C#的标准ui框架,wpf则是另一种ui框架,随着.net Core的流行,它会是今后的主流选择,我们必须学习它。


系列贴子导航:

wpf快速了解(1)基础开发环境

wpf快速了解(2)事件驱动和数据驱动

wpf快速了解(3)MVVM模式,行为绑定

wpf快速了解(4)行为绑定,后续

wpf快速了解(5)数据集合的绑定


MVVM模式,它是三个词的缩写(Model, View, ViewModel),意义如下:


Model: 数据模型

它是把界面要显示的数据按面向对象方式进行表示出来,第2篇示例中的MainViewModel类定义的那些属性,就是数据模型做的事。


View: 界面

即xaml标签定义的界面。


ViewModel: 业务逻辑处理

如界面按钮这些控件的事件代码,就是业务逻辑处理的代码。



MVVM模式把桌面软件的开发分为上面说的三个层面(Model, View, ViewModel),

最主要的是把View和ViewModel进行解耦,以达到界面与业务逻辑的分离。

而Model和ViewModel是一个强关联的关系,这一点,通过本篇文章你就会看得到。

Model可以有许多个(因为复杂界面的数据更新是按功能进行分块的),这样ViewModel中可以有多个Model。



通过上篇贴子《wpf快速了解(2)事件驱动和数据驱动》完成了数据驱动的演示后,该代码离MVVM模式比较接近了。

本篇完成后,基本上就能看到MVVM模式的样子了。


勇哥说下本篇的新需求:

仍然实现上篇的功能,但是要求按钮事件里完全没有代码,即下面的代码都没有了。

private void ButRead_Click(object sender, RoutedEventArgs e)
        {
            model.Value = "100";
        }

这样整个界面后台代码只存在一句 this.DataContext = model;

        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = model;
        }



我们先在MainViewModel中添加一个属性。

 private ICommand myCommandValue;

 public ICommand MyCommandValue
 {
    get { return myCommandValue; }
    set { myCommandValue = value; }
 }



把“读”按钮的Click删除掉,换成Command

这个Command实际还是Click事件,但是它可以绑定对象属性MyCommandValue,

点击按钮后会执行这个属性的代码。

image.png

下面的 {Binding MyCommandValue} 即是本文的主题“行为绑定”。

<Button Name="ButRead" Content="读" HorizontalAlignment="Left" Margin="22,173,0,0" VerticalAlignment="Top" Height="24" Width="78" Grid.Column="1" 
  Command="{Binding MyCommandValue}"
 />


由于上面的属性MyCommandValue,它的类型是一个接口ICommand,所以我们得做一个实现类。

这个实现类的默认内容如下:

两个方法,一个事件,啥用处?继续看。。。

    internal class CommandValue : ICommand
    {
        public event EventHandler? CanExecuteChanged;

        public bool CanExecute(object? parameter)
        {
            throw new NotImplementedException();
        }

        public void Execute(object? parameter)
        {
            throw new NotImplementedException();
        }
    }

回到MainViewModel的MyCommandValue属性定义。

这里我们new一个CommandValue做为myCommandValue的初始值。

 private ICommand myCommandValue=new CommandValue();

        public ICommand MyCommandValue
        {
            get { return myCommandValue; }
            set { myCommandValue = value; }
        }


好了,我们来研究第一个方法Execute,它是带参数的。

这个参数调用者可以不传,但是如果要专的话,要在xaml里面加标签。

 public void Execute(object? parameter)
        {
            throw new NotImplementedException();
        }

如下:

添加属性 CommandParameter传入参数。执行后字符串"hackpig"会传入函数Excute

<Button Name="ButRead" Content="读" HorizontalAlignment="Left" Margin="22,173,0,0" VerticalAlignment="Top" Height="24" Width="78" Grid.Column="1" 
                Command="{Binding MyCommandValue}"
                CommandParameter="hackpig"
/>


我们来完成函数Excute的功能,但是出现下面注释的问题。

怎么办?

        public void Execute(object? parameter)
        {
            //控制逻辑
            //此处原意是想写 Value=100,但是此处访问不到Value

        }


这时候我们可以定义一个委托,然后在后面再让ICommand接口的 MyCommandValue属性去执行这个委托。

如下:

    internal class CommandValue : ICommand
    {
        public event EventHandler? CanExecuteChanged;

        public bool CanExecute(object? parameter)
        {
            return true;
        }

        public void Execute(object? parameter)
        {
            //控制逻辑
            //此处原意是想写 Value=100,但是此处访问不到Value
            OnAction?.Invoke(parameter);
        }

        public Action<object?> OnAction { get; set; }
        
    }

MyCommandValue属性这边我们这样写:

       private ICommand myCommandValue;

        public ICommand MyCommandValue
        {
            get 
            {
                if (myCommandValue == null)
                {
                    myCommandValue = new CommandValue()
                    {
                       OnAction = new Action<object?>(Action1)
                    };
                }
                return myCommandValue;
            }
            set { myCommandValue= value; }
        }

        private void Action1(object? para)
        {
            Value= "100";
        }


至此,勇哥已经完成了本例的要求,如下图所示:

我们在UI的后台代码中已经看到了跟业务逻辑有关的任何代码了。

就只剩下那一句“this.DataContext = model;”

image.png


至此,我们的MVVM模式已经基本成型了。




本文源码下载:

支付2元或购买VIP会员后,才能查看本内容!立即支付升级会员查询订单


--------------------- 

作者:hackpig
来源:www.skcircle.com
版权声明:本文为博主原创文章,转载请附上博文链接!



本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

会员中心
搜索
«    2024年5月    »
12345
6789101112
13141516171819
20212223242526
2728293031
网站分类
标签列表
最新留言
    热门文章 | 热评文章 | 随机文章
文章归档
友情链接
  • 订阅本站的 RSS 2.0 新闻聚合
  • 扫描加本站机器视觉QQ群,验证答案为:halcon勇哥的机器视觉
  • 点击查阅微信群二维码
  • 扫描加勇哥的非标自动化群,验证答案:C#/C++/VB勇哥的非标自动化群
  • 扫描加站长微信:站长微信:abc496103864
  • 扫描加站长QQ:
  • 扫描赞赏本站:
  • 留言板:

Powered By Z-BlogPHP 1.7.2

Copyright Your skcircle.com Rights Reserved.

鄂ICP备18008319号


站长QQ:496103864 微信:abc496103864