zoukankan      html  css  js  c++  java
  • wp8使用mvvm模式简单例子(二)---登陆功能,事件触发

    首先,还是需要一个Model类来为UI层的元素提供数据源

    public class LoginModel:DependencyObject
        {
    
    
            public string Uid
            {
                get { return (string)GetValue(UidProperty); }
                set { SetValue(UidProperty, value); }
            }
    
            // Using a DependencyProperty as the backing store for Uid.  This enables animation, styling, binding, etc...
            public static readonly DependencyProperty UidProperty =
                DependencyProperty.Register("Uid", typeof(string), typeof(LoginModel), null);
    
    
    
            public string Pwd
            {
                get { return (string)GetValue(PwdProperty); }
                set { SetValue(PwdProperty, value); }
            }
    
            // Using a DependencyProperty as the backing store for Pwd.  This enables animation, styling, binding, etc...
            public static readonly DependencyProperty PwdProperty =
                DependencyProperty.Register("Pwd", typeof(string), typeof(LoginModel),null );
    
            public ICommand LoginCmd
            {
                get
                {
                    return new LoginCommand();
                }
            }
        }


    和一个继承ICommand接口的类LoginCommand

    <pre name="code" class="csharp">public class LoginCommand:ICommand
        {
            public bool CanExecute(object parameter)
            {
                return true;
            }
    
            public void Execute(object parameter)
            {
                LoginModel login = (LoginModel) parameter;
                if (login.Uid == "admin" && login.Pwd == "111")
                {
                    MessageBox.Show("ok");
                }
                else
                {
                    MessageBox.Show("error");
                }
            }
    
            public event EventHandler CanExecuteChanged;
        }


    
    


    然后为前台的UI元素绑定数据源:

    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="14,10,10,-10" Grid.ColumnSpan="2" DataContext="{StaticResource loginModel}">
                <TextBox Name="txtUid" Text="{Binding Uid,Mode=TwoWay}" HorizontalAlignment="Left" Height="72" Margin="115,35,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="224"/>
                <TextBox Name="txtPwd" Text="{Binding Pwd,Mode=TwoWay}" HorizontalAlignment="Left" Height="72" Margin="115,138,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="224"/>
                <TextBlock Text="账号:"  HorizontalAlignment="Left" Margin="28,60,0,0" TextWrapping="Wrap" VerticalAlignment="Top" RenderTransformOrigin="-0.146,-0.259"/>
                <TextBlock Text="密码:" HorizontalAlignment="Left" Margin="28,163,0,0" TextWrapping="Wrap" VerticalAlignment="Top" RenderTransformOrigin="-0.146,-0.259"/>
                <Button Content="登陆" Command="{Binding LoginCmd}" CommandParameter="{Binding}" HorizontalAlignment="Left" Margin="28,246,0,0" VerticalAlignment="Top"/>
            </Grid>

    这样看起来似乎没有任何问题

    启动调试,点击按钮进行判断,完美运行



    但是肯定是有地方不对劲

    那到底是哪里的问题?

    仔细想想mvvm的原则

    在xaml.cs后台不直接操作UI元素

    Model提供数据源

    UI元素绑定数据源

    LoginCommand的Execute方法进行业务逻辑处理

    其实在前面的Execute方法的业务处理代码中已经违反了mvvm的规定

    public void Execute(object parameter)
            {
                LoginModel login = (LoginModel) parameter;
                if (login.Uid == "admin" && login.Pwd == "111")
                {
                    MessageBox.Show("ok");
                }
                else
                {
                    MessageBox.Show("error");
                }
            }
    这里只能写逻辑处理的代码

    不能有控制UI的部分

    上面这么写就相当于asp.net的三层中在Bll层突然来了个Response.Redirect一样

    这很明显是不允许的!


    那么要如何修改呢?

    首先

    既然对MessageBox明确了不能出现在这里

    那么只能在xaml.cs后台文件中进行处理了

    那么后台又不能包含有任务业务处理的代码

    他怎么才能知道什么时候要Show一下信息,然后Show什么信息呢?


    这就要用到一个事件机制了

    先定义一个委托

    public delegate void LoginResult(bool success);


    然后在LoginModel中定义一个事件

    public event LoginResult LoginCompelete;


    在后台页面加载的事件中对该事件添加方法

    private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
            {
                LoginModel model = (LoginModel)this.Resources["loginModel"];
                model.LoginCompelete += new LoginResult(model_LoginCompelete);
            }
    
            void model_LoginCompelete(bool success)
            {
                if (success)
                {
                    MessageBox.Show("ok!");
                }
                else
                {
                    MessageBox.Show("error!");
                }
            }

    而这时,LoginCommand的Execute方法就需要进行修改了

    既然在页面加载的时候  就已经为LoginModel的LoginCompelete事件添加完了显示MessageBox的方法

    那么在Execute中需要做的事情就只是  判断用户的账号密码

    然后根据结果触发这个事件就ok了

    但是因为事件本质是一个私有的委托+add和remove两个属性

    所以该事件只能在内部被触发


    所以在LoginModel中需要提供一个方法,让外界能够通过该方法触发LoginCompelete事件

    public void FirLoginCompelete(bool success)
            {
                if (LoginCompelete != null)
                {
                    LoginCompelete(success);
                }
            }


    之后就可以再Execute方法中方便的触发事件了

    public void Execute(object parameter)
            {
                LoginModel login = (LoginModel) parameter;
                if (login.Uid == "admin" && login.Pwd == "111")
                {
                    login.FirLoginCompelete(true);
                }
                else
                {
                    login.FirLoginCompelete(false);
                }
            }



    修改完成!


  • 相关阅读:
    wepy框架入门
    认识WebStorm-小程序框架wepy
    列表
    透明盒子
    wepy框架滑动组件使用
    底部导航栏效果
    安装less/sass
    wepy快速入门
    实现返回顶部-wepy小程序-前端梳理
    音乐播放器-图片切换-轮播图效果
  • 原文地址:https://www.cnblogs.com/jchubby/p/4429741.html
Copyright © 2011-2022 走看看