WPF MVVM文本框绑定

时间:2015-07-25 14:39:07

标签: c# wpf mvvm binding textbox

更新

我使用此自定义实现here。使用棱镜的弱引用存在问题。

我是MVVM和Microsofts Prism的新手。我试图让我的文本框上的绑定工作。如果文本框不为空,则登录按钮应可用。 setter正在运行,但CanOnLogin()始终返回false。

模型

class UserModel
{
    private string userName;
    private string passWord;
    public string UserName
    {
        get { return userName; }
        set { userName = value; }
    }


    public string PassWord
    {
        get { return passWord; }
        set { passWord = value; }
    }
}

视图模型

class LoginViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private UserModel user;
    private DelegateCommand _loginCommand;
    public UserModel User 
    { 
        get { return user; }
        set { user = value; }
    } 

    public string UserName
    {
        get { return user.UserName; }
        set
        {
            user.UserName = value;
            OnPropertyChanged("UserName");
        }
    }

    public ICommand LoginCommand
    {
        get { return _loginCommand; }
    }

    public LoginViewModel() 
    {
        _loginCommand = new DelegateCommand(OnLogin, CanOnLogin);
        //implement CanOnLoginChanged here?
        user = new UserModel();
    }

    private bool CanOnLogin()
    {
        if (String.IsNullOrEmpty(user.UserName))
        {
            return false;
        }
        else 
        {
            return true; 
        }
    }

    private void OnLogin() 
    {
    // Do something here
        MessageBox.Show(user.UserName);
    }

    private void OnPropertyChanged(string propName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
    }

    public event EventHandler CanOnLoginChanged
    {
        add
        {
            CommandManager.RequerySuggested += value;
        }
        remove
        {
            CommandManager.RequerySuggested -= value;
        }
    }
}

查看

<TextBox Name="username" Text="{Binding Path=UserName, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" HorizontalAlignment="Center" Margin="10" Width="175" Grid.Row="1" Grid.Column="0" Controls:TextBoxHelper.Watermark="Username" Controls:TextBoxHelper.ClearTextButton="True"/>
<Button HorizontalAlignment="Center" Margin="10" Width="87.5" Grid.Row="3" Grid.Column="0" Command="{Binding LoginCommand}">Login</Button>

代码隐藏

public partial class LoginView : MetroWindow
{
    public LoginView()
    {
        InitializeComponent();
        DataContext = new LoginViewModel();
    }
}

3 个答案:

答案 0 :(得分:0)

问题是你必须创建canExecuteChanged: 它现在会起作用。

 public event EventHandler CanExecuteChanged {
        add {
            CommandManager.RequerySuggested += value;
        }
        remove {
            CommandManager.RequerySuggested -= value;
        }
    }

可以执行将检查是否有任何可能改变状态的相关事件,并且如果找到则将状态从false更改为true。

答案 1 :(得分:0)

我相信你并没有将对象参数作为参数传递给OnLogin和CanOnLogin,这就是为什么它不能为我工作并实现canOnLogInChanged而不是在我所做的任何属性或方法中,或者只是采取这个代码并再试一次:

using System;
using System.Windows.Input;
class LoginViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private UserModel user;
    private DelegateCommand _loginCommand;
    public UserModel User
    {
        get { return user; }
        set { user = value; }
    }

    public string UserName
    {
        get { return user.UserName; }
        set
        {
            user.UserName = value;
            OnPropertyChanged("UserName");
        }
    }

    public ICommand LoginCommand
    {
        get { return _loginCommand; }
    }

    public LoginViewModel()
    {
        _loginCommand = new DelegateCommand(OnLogin, CanOnLogin);
        //implement CanOnLoginChanged here?
        user = new UserModel();
    }

    private bool CanOnLogin(object parameter)
    {
        if (String.IsNullOrEmpty(user.UserName))
        {
            return false;
        }
        else
        {
            return true;
        }
    }
    public event EventHandler CanOnLoginChanged
    {
        add
        {
            CommandManager.RequerySuggested += value;
        }
        remove
        {
            CommandManager.RequerySuggested -= value;
        }
    }
    private void OnLogin(object parameter)
    {
        // Do something here
        MessageBox.Show(user.UserName);
    }

    private void OnPropertyChanged(string propName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
    }


}

答案 2 :(得分:0)

CanOnLogin 中,您应该检查ViewModel中的Property,PropertyChanged可以工作:

String.IsNullOrEmpty(UserName)

如果这没有用,请尝试设置延迟加载命令,以确保首先正确初始化所有数据。像

这样的东西
public ICommand LoginCommand
{
    get { return _loginCommand ?? (_loginCommand = new DelegateCommand(OnLogin, CanOnLogin)); }
}

或更改LoginViewModel()中的Initialisation-Order:

user = new UserModel();
_loginCommand = new DelegateCommand(OnLogin, CanOnLogin);

你是对的:棱镜委托命令总是不像我期望的那样工作。报告here

查看自定义实施的Example

希望这有帮助!