WPF中模型视图与视图模型的关系

时间:2016-07-22 06:22:07

标签: wpf mvvm

我使用MVVM创建了登录身份验证,并且运行正常。这就是我所做的:

MainWinodw.xaml

  <Window.Resources>
    <BooleanToVisibilityConverter x:Key="BoolToVis" />
</Window.Resources>
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <TextBlock Grid.Row="0" Grid.Column="0">UserName:</TextBlock>
    <TextBlock Grid.Row="1" Grid.Column="0">Password:</TextBlock>
    <TextBox Grid.Row="0" Grid.Column="1" Text="{Binding UserName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
    <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Password, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
    <Label Grid.Row="3" Grid.ColumnSpan="2" Visibility="{Binding isAuthenticated, Converter={StaticResource BoolToVis}}">
        User has been authenticated
    </Label>
    <Label Grid.Row="3" Grid.ColumnSpan="2" Visibility="{Binding LoginFail, Converter={StaticResource BoolToVis}}">
         Please enter valid  UserName and Password
    </Label>

    <Button Grid.Row="2" Grid.Column="1" Content="Authenticate" Command="{Binding LoginCommand}" Margin="3" Width="100" HorizontalAlignment="Right" />
</Grid>

UserViewModel.cs

public class LoginViewModel : INotifyPropertyChanged
{
    private bool _isAuthenticated;
    public bool isAuthenticated
    {
        get { return _isAuthenticated; }
        set
        {
            if (value != _isAuthenticated)
            {
                _isAuthenticated = value;
                OnPropertyChanged("isAuthenticated");
            }
        }
    }

    private bool _loginFail;
    public bool LoginFail
    {
        get { return _loginFail; }
        set
        {
            if (value != _loginFail)
            {
                _loginFail = value;
                OnPropertyChanged("LoginFail");
            }
        }
    }

    private string _username;
    public string UserName
    {
        get { return _username; }
        set
        {
            _username = value;
            OnPropertyChanged("UserName");
        }
    }

    private string _password;
    public string Password
    {
        get { return _password; }
        set
        {
            _password = value;
            OnPropertyChanged("Password");
        }
    }

    public ICommand LoginCommand
    {
        get { return new RelayCommand(param => this.Login()); }
    }

    public void Login()
    {
        //TODO check username and password vs database here.
        //If using membershipprovider then just call Membership.ValidateUser(UserName, Password)
        //if (!String.IsNullOrEmpty(UserName) && !String.IsNullOrEmpty(Password))
        //    isAuthenticated = true;
        isAuthenticated = LoginDataLayer.AuthenticateUser(UserName, Password);
        if(isAuthenticated == true)
        {
            LoginFail = false;
        }
        else
        {
            LoginFail = true;
        }

    }

    #region INotifyPropertyChanged Methods

    public void OnPropertyChanged(string propertyName)
    {
        this.OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
    }

    protected virtual void OnPropertyChanged(PropertyChangedEventArgs args)
    {
        if (this.PropertyChanged != null)
        {
            this.PropertyChanged(this, args);
        }
    }


    public event PropertyChangedEventHandler PropertyChanged;

    #endregion
}

这很好用。但正如我所说,我是MVVM的新手。我也在viewmodel中编写模型代码。在意识到我的错误后,我尝试将模型和视图模型代码分开,如下所示:

UserModel.cs

 public  class UserModel : INotifyPropertyChanged
{
    private bool _isAuthenticated;
    public bool isAuthenticated
    {
        get { return _isAuthenticated; }
        set
        {
            if (value != _isAuthenticated)
            {
                _isAuthenticated = value;
                OnPropertyChanged("isAuthenticated");
            }
        }
    }

    private bool _loginFail;
    public bool LoginFail
    {
        get { return _loginFail; }
        set
        {
            if (value != _loginFail)
            {
                _loginFail = value;
                OnPropertyChanged("LoginFail");
            }
        }
    }

    private string _username;
    public string UserName
    {
        get { return _username; }
        set
        {
            _username = value;
            OnPropertyChanged("UserName");
        }
    }

    private string _password;
    public string Password
    {
        get { return _password; }
        set
        {
            _password = value;
            OnPropertyChanged("Password");
        }
    }

    #region INotifyPropertyChanged Methods

    public void OnPropertyChanged(string propertyName)
    {
        this.OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
    }

    protected virtual void OnPropertyChanged(PropertyChangedEventArgs args)
    {
        if (this.PropertyChanged != null)
        {
            this.PropertyChanged(this, args);
        }
    }


    public event PropertyChangedEventHandler PropertyChanged;

    #endregion
}

UserViewModel.cs

public void Login()
    {
        UserModel obj = new UserModel();


        obj.isAuthenticated = LoginDataLayer.AuthenticateUser(obj.UserName,obj. Password);
        if(obj.isAuthenticated == true)
        {
           obj.LoginFail = false;
        }
        else
        {
            obj.LoginFail = true;
        }

    }

但是我得到了obj.username为null。所以任何人都可以帮助我如何在视图模型中获取模型属性以及如何更新。请帮忙。 感谢

1 个答案:

答案 0 :(得分:1)

正如我所看到的,您的view datacontext是viewModel,但属性在Model上。从View模型中访问UserModel,如下所示:

视图模型:

private UserModel _userModel;
public UserModel userModel
{
    get { return _userModel; }
    set
    {
        _userModel = value;
        OnPropertyChanged("userModel");
    }
}

查看:

<TextBox Text="{Binding userModel.UserName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />