簡體   English   中英

WPF MVVM文本框綁定

[英]WPF MVVM textbox binding

UPDATE

我懂了這個自定義實現工作在這里 使用棱鏡的弱參考存在問題。

我是MVVM和Microsoft Prism的新手。 我正在嘗試使我的文本框上的綁定起作用。 如果文本框不為空,則登錄按鈕應該可用。 設置器正在運行,但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();
    }
}

問題是您必須創建canExecuteChanged:它將立即運行。

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

可以執行將檢查是否存在任何可能改變狀態的相關事件,如果發現一個事件,則將狀態從false更改為true。

我相信您沒有將對象參數作為參數傳遞給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));
    }


}

CanOnLogin中,您應該從ViewModel中檢查Property,以確保PropertyChanged可以正常工作:

String.IsNullOrEmpty(UserName)

如果那沒有幫助,請嘗試設置您的命令以進行延遲加載,以確保首先正確初始化所有數據。 就像是

public ICommand LoginCommand
{
    get { return _loginCommand ?? (_loginCommand = new DelegateCommand(OnLogin, CanOnLogin)); }
}

或在LoginViewModel()中更改Initialization-Order:

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

您說得對: Prism Delegate Command並非總是像我期望的那樣工作。 在這里報道。

查看此自定義實現示例

希望這可以幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM