初识MVVM

MVVM分解:


M->   源数据一堆get,set方法,对应Java中,JavaBean

V->    窗体,显示界面

VM-> 业务逻辑层,对窗体的逻辑响应,及数据传输的处理。


这样做的优点:

窗体改变,只需变动窗体样式,绑定对应的数据及响应事件(VM)。

VM只需处理逻辑改变

M只需添加数据或删除数据,及将数据变化反馈给UI


MVVM需要实现两个关键接口。

A)  ICommand接口,此接口用于实现界面响应事件的委托

B)  INotifyPropertyChanged接口,此接口用于实现 界面和数据源同步变化


以登录窗体为例,实现

A)修改Module中数据,改变界面显示

B)修改界面输入数据,同步Module中的数据


1)新建工程,KnowXAML

主界面类.cs如下:

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Data;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Imaging;

using System.Windows.Navigation;

using System.Windows.Shapes;

using KnowXAML.ModuleView;

 

namespace KnowXAML

{

    ///<summary>

    /// Interaction logic for MainWindow.xaml

    ///</summary>

    public partial class MainWindow : Window

    {

        public MainWindow()

        {

           InitializeComponent();

        }

    }

}

 

2新建ICommand界面命令代理类 UICommand. UICommand用于实现空间响应事件的代理。

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows.Input;

 

namespace KnowXAML.DelegateCommand

{

    class UICommand : ICommand

    {

        ///<summary>

        ///判断控件是否可用

        ///</summary>

        Func<object, bool> canExecute;

 

        ///<summary>

        ///执行方法

        ///</summary>

        Action<object> executeAction;

 

        bool canExecuteCache;

        public event EventHandler CanExecuteChanged;

 

        public UICommand(Action<object> executeAction, Func<object, bool> canExecute)

        {

            this.executeAction = executeAction;

            this.canExecute = canExecute;

        }

 

        bool ICommand.CanExecute(objectparameter)

        {

            bool temp = canExecute(parameter);

            if (canExecuteCache != temp)

            {

               canExecuteCache = temp;

               if (CanExecuteChanged != null)

                   CanExecuteChanged(this, newEventArgs());

            }

            return canExecuteCache;

        }

 

        void ICommand.Execute(object parameter)

        {

           executeAction(parameter);

        }

    }

}

 

3)创建类UINotifier实现界面数据同步接口INotifyPropertyChanged此类用于同步界面和底层类(Bean)数据。

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.ComponentModel;

 

namespace KnowXAML.DelegateNotifer

{

    public abstract class UINotifier : INotifyPropertyChanged

    {

        #region INotifyPropertyChanged

        publiceventPropertyChangedEventHandler PropertyChanged;

        #endregion

 

        #region Protected

        protectedvirtualvoid OnPropertyChanged(stringpropertyName)

        {

            if (PropertyChanged != null)

               PropertyChanged(this, newPropertyChangedEventArgs(propertyName));

        }

        #endregion

    }

}

 

4创建底层数据类(Bean,User,继承类DelegateNotifer

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Windows;

using System.Threading.Tasks;

using KnowXAML.DelegateNotifer;

 

namespace KnowXAML.Module

{

    public class User : UINotifier

    {

        private string userName;

        public string Name

        {

            get

            {

               return userName;

            }

            set

            {

               userName = value;

               OnPropertyChanged("Name");

           }           

        }

 

        private string userPassword;

        public string Password

        {

            get

            {

               return userPassword;

            }

            set

            {

               userPassword = value;

               OnPropertyChanged("Password");

            }

        }

    }

}

 

5)创建ModuleView类,用于User类和界面的数据桥接。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using KnowXAML.Module;

using KnowXAML.DelegateCommand;

using KnowXAML.DelegateNotifer;

 

namespace KnowXAML.ModuleView

{

    class UserModuleView

    {

        public User user { get; set; }

        public UICommand uiCommand { get; set; }

 

        public UserModuleView()

        {

            this.user = newUser();

            this.uiCommand = new UICommand(SetUserInfo, arg=>true); //指定命令外//部接口uiCommand对应函数为SetUserInfouiCommand用于XMAL中配置

        }

 

        public void SetUserInfo(object parm)

        {

           user.Name = "zhangsan";

           user.Password = "123124";

        }

 

        public User userMode

        {

            get

            {

               return user;

            }

            set

            {

               if (user == value)

                   return;

               user = value;

            }

        }

 

    }

}

 

6)添加控件,修改XMAL,添加数据绑定及响应事件。黄色背景处为添加数据源,及响应事件项。

 

XMAL格式如下:

<Window x:Class="KnowXAML.MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

        xmlns:local="clr-namespace:KnowXAML"

        xmlns:vm="clr-namespace:KnowXAML.ModuleView"

        mc:Ignorable="d"

        Title="MainWindow"Height="277.407" Width="525">

   <Window.DataContext>

        <vm:UserModuleView />

   </Window.DataContext>

    <Grid>

        <Grid.ColumnDefinitions>

            <ColumnDefinition Width="118*"/>

            <ColumnDefinition Width="401*"/>

        </Grid.ColumnDefinitions>

 

        <GroupBox x:Name="groupBox"Header="GroupBox" HorizontalAlignment="Left"Margin="10,26,0,-0.4"VerticalAlignment="Top" Height="224"Width="498" Background="AliceBlue"Grid.ColumnSpan="2">

            <Grid HorizontalAlignment="Left"Margin="10,10,-3.2,34.4" Width="478">

               <Grid.ColumnDefinitions>

                   <ColumnDefinitionWidth="115*"/>

                   <ColumnDefinitionWidth="363*"/>

               </Grid.ColumnDefinitions>

               <Label x:Name="lblUserName"Content="UserName:"HorizontalAlignment="Left" Margin="31,24,0,0"VerticalAlignment="Top" Width="86"FontSize="16" Grid.ColumnSpan="2"/>

               <TextBox x:Name="txtUserName"HorizontalAlignment="Left" Height="27" Margin="20.587,29,0,0" Text="{Binding Path= userMode.Name}"TextWrapping="Wrap" VerticalAlignment="Top"Width="251" FontSize="16"Grid.Column="1"/>

               <Label x:Name="lblPassword"Content="Password:" FontSize="16" HorizontalAlignment="Left"Margin="36,82,0,0"VerticalAlignment="Top"RenderTransformOrigin="-0.205,0.338"Grid.ColumnSpan="2"/>

               <TextBox x:Name="txtPassword"HorizontalAlignment="Left" FontSize="16"Text="{Binding Path= userMode.Password}" Height="25"Margin="20.587,88,0,0"TextWrapping="Wrap" VerticalAlignment="Top"Width="251" Grid.Column="1"/>

               <Button x:Name="btnCancel"Content="Cancel"HorizontalAlignment="Left" Margin="62.587,132,0,0"VerticalAlignment="Top" Width="75"Grid.Column="1"/>

               <Button x:Name="btnOK" Command="{Binding uiCommand}" Content="OK"HorizontalAlignment="Left" Margin="196.587,132,0,0"VerticalAlignment="Top" Width="75"Grid.Column="1"/>

            </Grid>

        </GroupBox>

    </Grid>

</Window>

 

7)运行界面

初始化界面:


点击“OK”后界面

修改UserName后,点击“OK”


如果觉得我写的还不错,请关注我的微信:






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值