您如何从具有数据绑定属性的文本框中获取文本通知事物 mvvm 灯

本文关键字:取文本 获取 通知 mvvm 文本 属性 数据绑定 | 更新日期: 2023-09-27 18:34:23

  • 我有一个用户名和密码框。
  • 在它下面,我有一个按钮。
  • 当我单击该按钮时,我想分析用户名和密码框中输入的内容。

如何使用 mvvm 灯执行此操作?

这就是我所在的地方:

XAML

...DataContext="{Binding Main, Source={StaticResource Locator}}">...
    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0">
        <TextBlock HorizontalAlignment="Left" Margin="10,0,0,0" TextWrapping="Wrap" Text="Username" VerticalAlignment="Top"/>
        <TextBox HorizontalAlignment="Left" Height="72" Margin="0,27,0,0" TextWrapping="Wrap" Text="{Binding Username}" VerticalAlignment="Top" Width="456"/>
        <TextBlock HorizontalAlignment="Left" Margin="10,99,0,0" TextWrapping="Wrap" Text="Password" VerticalAlignment="Top"/>
        <PasswordBox HorizontalAlignment="Left" Height="72" Margin="0,126,0,0" Password="{Binding Password}" VerticalAlignment="Top" Width="456"/>
        <Button Content="Log in" HorizontalAlignment="Center" Margin="167,203,169,0" VerticalAlignment="Top" Command="{Binding LogInCommand}"/>
    </Grid>

查看模型

public class MainViewModel : ViewModelBase
{
    public LoginCredentials LoginCredentials { get; set; }        
    public ICommand LogInCommand { get; private set; }
    public MainViewModel()
    {
        LoginCredentials = new LoginCredentials();
        LogInCommand = new RelayCommand(this.OnLogInCommand);
    }
    private void OnLogInCommand()
    {
        string testUsername = Username;
        string testPassword = Password;
    }
    #region Properties
    public string Username
    {
        get { return LoginCredentials.Username; }
        set { LoginCredentials.Password = value; }
    }
    public string Password
    {
        get { return LoginCredentials.Password; }
        set { LoginCredentials.Password = value; }
    }
    #endregion
}

MainPage.xaml.cs

public partial class MainPage : PhoneApplicationPage
{
    public MainPage()
    {
        InitializeComponent();
    }
}

目前正在发生的事情:

  • 当我单击我的按钮时,LogInCommand 将运行并触发我的方法 OnLoginCommand。我在testUsername 声明上放置了一个断点,以查看单击按钮时,用户名和密码是否反映了已输入的内容;它们都是空的。我必须怎么做才能确保在有人打字或按下按钮或工作方式时更新这些内容???

我现在花了大约 4 周的时间学习 mvvm,并尝试让一个简单的点击事件和绑定工作。这根本说不通...嘟嘟。感谢您的任何帮助!

附言 - MVVM 轻量级对新人来说是否太混乱了? 文档是如此..细节轻。没有示例:(

您如何从具有数据绑定属性的文本框中获取文本通知事物 mvvm 灯

视图

Windows Phone 不包含"UpdateSourceTrigger=PropertyChanged"。您必须使用">显式"并在代码隐藏中手动调用">UpdateSource",否则当文本框/密码框失去焦点时,将引发文本框/密码框的值。

并且不要忘记设置">模式=双向"。

<TextBox
    Text="{Binding Path=Username, Mode=TwoWay, UpdateSourceTrigger=Explicit}"
    TextChanged="TextBoxTextChanged" />
<PasswordBox
    Password="{Binding Path=Password, Mode=TwoWay, UpdateSourceTrigger=Explicit}"
    PasswordChanged="PasswordBoxPasswordChanged" />
<Button
    Command="{Binding Path=LogInCommand}"
    Content="Log in" />

视图 - 代码隐藏

private void PasswordBoxPasswordChanged(object sender, RoutedEventArgs e)
{
    PasswordBox pb = sender as PasswordBox;
    if (pb != null)
    {
        pb.GetBindingExpression(PasswordBox.PasswordProperty).UpdateSource();
    }
}

private void TextBoxTextChanged(object sender, TextChangedEventArgs e)
{
    TextBox tb = sender as TextBox;
    if (tb != null)
    {
        tb.GetBindingExpression(TextBox.TextProperty).UpdateSource();
    }
}

视图模型

领域

private RelayCommand _logInCommand;
private string _password;
private string _username;

性能

public bool CanExecuteLogInCommand
{
    get
    {
        return !string.IsNullOrWhiteSpace(this.Username) && !string.IsNullOrWhiteSpace(this.Password);
    }
}
    public RelayCommand LogInCommand
    {
        get
        {
            // or you can create instance in constructor: this.LogInCommand = new RelayCommand(this.ExecuteLogInCommand, () => this.CanExecuteLogInCommand);
            return this._logInCommand ?? (this._logInCommand = new RelayCommand(this.ExecuteLogInCommand, () => this.CanExecuteLogInCommand));
        }
    }
    public string Username
    {
        get { return this._username; }
        set
        {
            // a) shorter alternative -> "True if the PropertyChanged event has been raised, false otherwise"
            if (this.Set(() => this.Username, ref this._username, value))
            {
                // raise CanExecuteLogInCommand
                this.LogInCommand.RaiseCanExecuteChanged();
            }

            // b) longer alternative
            //if (value == this._username) { return; }
            //this._username = value;
            //this.RaisePropertyChanged(() => this.Username);
            //this.LogInCommand.RaiseCanExecuteChanged();
        }
    }
    public string Password
    {
        get { return this._password; }
        set
        {
            if (this.Set(() => this.Password, ref this._password, value))
            {
                this.LogInCommand.RaiseCanExecuteChanged();
            }
        }
    }

方法

    private void ExecuteLogInCommand()
    {
        // .... = this.Username;
        // .... = this.Password;
    }

检查此示例

要使视图和 ViewModel "链接"以便它们同步,您需要实现 INotifyPropertyChanged (封装在 ViewModelBase 中(。 即:

private string userName;
public string UserName
{
    get { return userName; }
    set
    {
        if (value != userName)
        {
            userName = value;
            RaisePropertyChanged("UserName");
        }
    }
}