MVVM - 绑定和更改

时间:2016-04-27 12:38:43

标签: c# wpf mvvm navigation passwords

实际状态:我单击“登录”按钮,ViewModel将更改为新视图。

所需状态:我点击LoginButton(LoginViewModel与视图绑定以获取电子邮件和密码,并在服务器中验证用户的真实性,如果确定,请求收到有关用户和更改的信息作为答案视图)

我所知道的:更改视图,绑定文本框,与服务器通信(处理请求和答案)

我不知道的事情:从LoginViewModel向GeneralViewModel发送有关用户信息的答案,不知道如何维护PasswordBox而不是TextBox进行绑定。

CODE: LoginView

<Grid Margin="0,0,-74.4,-11.8" HorizontalAlignment="Left" Width="800" Height="600" VerticalAlignment="Top">

    <TextBox Text = "{Binding Email, Mode = TwoWay}" Style="{DynamicResource MyTextBox}" x:Name="textBoxEmail" VerticalContentAlignment="Bottom" HorizontalContentAlignment="Center" HorizontalAlignment="Center"  Width="248" Margin="274,212,278,347" FontFamily="Segoe UI Semibold" />

    <Image Source="C:\Users\Images\logo.png" x:Name="Logo" HorizontalAlignment="Left" Height="129" Margin="301,63,0,0" VerticalAlignment="Top" Width="151" RenderTransformOrigin="0.5,0.5">
        <Image.RenderTransform>
            <TransformGroup>
                <ScaleTransform/>
                <SkewTransform/>
                <RotateTransform Angle="0.091"/>
                <TranslateTransform/>
            </TransformGroup>
        </Image.RenderTransform>
    </Image>

                           立即注册!         忘记密码了吗?点击这里!     

LoginViewModel

 class LoginViewModel : AViewModel
{
    WifiAP wa;
    #region fields
    private string _email = null;
    private TokenRequest tk;
    public DelegateCommand LoginCommand { get; set; }

    public string Email
    {
        get
        {
            return _email;
        }
        set
        {
            _email = value;
            OnPropertyChanged("Email");
            //Here's the magic
            LoginCommand.RaiseCanExecuteChanged();
        }
    }
    private string _password = null;

    public string Password
    {
        get
        {
            return _password;
        }
        set
        {
            _password = value;
            OnPropertyChanged("Password");
            //Here's the magic
            LoginCommand.RaiseCanExecuteChanged();
        }
    }
    public string mac;
    #endregion

    public LoginViewModel()
    {
        wa = new WifiAP();
        LoginCommand = new DelegateCommand(Login, CanLogin);

    }

    public bool CanLogin()
    {
        return !string.IsNullOrEmpty(Email);
    }

    public void Login()
    {
        //
    }


    #region auxiliaryMethods
    public string getMac()
    {
        mac = wa.GetMACAddress();
        return mac;
    }

    public string hashingMD5(string pass)
    {
        string pwd = pass;
        System.Security.Cryptography.MD5 hs = System.Security.Cryptography.MD5.Create();
        byte[] db = hs.ComputeHash(System.Text.Encoding.UTF8.GetBytes(pwd));
        string result = Convert.ToBase64String(db);
        return result;
    }}

MainViewModel

    public MainWindowViewModel{ 
this.AddViewModel(new LoginViewModel() { DisplayName = "Login", InternalName = "LoginViewModel" }); 
this.AddViewModel(new GeneralViewModel() { DisplayName = "General", InternalName = "GeneralViewModel" }); 
this.Current_ViewModel = this.GetViewModel("LoginViewModel");

提前感谢您的时间。

1 个答案:

答案 0 :(得分:0)

首先,here you have the article告诉您如何处理MVVM中的PasswordBox。其次,如何通过数据传递?我对MVVM Light不太熟悉,因为我个人使用PRSIM。你可能会做类似RegionContext的事情。

首先,您必须创建一个类作为RegionData。请注意,此模型还实现了OnPropertyChanged接口(该实现来自MVVM Light中继承的ViewModelBase)。

public class HaveLoginData : ViewModelBase
{
    private string _login;
    public string Login
    {
        get { return _login; }
        set
        {
            _login = value;
            RaisePropertyChanged(() => Login);
        }
    }
}

在构造函数中,您应该为两个ViewModel创建此类的公共实例:

    public MainWindowViewModel
    { 
        var regionData = new HaveLoginData();
        this.AddViewModel(new LoginViewModel() { RegionData = regionData }); 
        this.AddViewModel(new GeneralViewModel() { RegionData = regionData }); 
        this.Current_ViewModel = this.GetViewModel("LoginViewModel");
    }

您还必须向ViewModel添加一个名为RegionData的新属性:

using System.ComponentModel;

namespace YourApp.ViewModels
{
    public class GeneralViewModel
    {
        private HaveLoginData _regionData;
        public HaveLoginData RegionData
        {
            get { return _regionData; }
            set
            {
                _regionData = value;
                _regionData.PropertyChanged += _regionData_PropertyChanged;
            }
        }

        private void _regionData_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "Login")
            {
                // do the second view model login logic
            }
        }
    }
}

登录ViewModel:

namespace YourApp.ViewModels
{
    public class LoginViewModel
    {
        public HaveLoginData RegionData { get; set; }

        public void Login()
        {
            // do the login conditions logic
            if (true)
            {
                RegionData.Login = "new user login";
            }
        }
    }
}

如您所见,当有人设置RegionData时,您将订阅PropertyChanged事件,并在每个ViewModel中注意Login和MD5Password属性中的更改。如您所见,您还必须记住从之前的RegionData中取消订阅PropertyChanged事件。一旦创建了RegionData,就不应该更改它,因此在setter中可能没有必要(你可以使用某种Dispose来删除引用)。