1
  • ユーザー名とパスワードのボックスがあります。
  • その下にボタンがあります。
  • そのボタンをクリックすると、ユーザー名とパスワードのボックスに入力された内容を分析したいと思います。

mvvm light でこれを行うにはどうすればよいですか?

これは私がいる場所です:

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 宣言にブレーク ポイントを設定しました。どちらも空です。誰かが入力しているとき、またはボタンが押されたとき、またはそれが機能したときにこれらが更新されるようにするにはどうすればよいですか???

私は現在、mvvm を学習し、単純なクリック イベントとバインドを機能させるために約 4 週間を費やしました。これは単に意味がありません..。助けてくれてありがとう!

PS - MVVM ライトは新規参入者にとって混乱しすぎますか? ドキュメントはとても..詳細に光っています。例はありません:(

4

2 に答える 2

3

意見

Windows Phone には "UpdateSourceTrigger=PropertyChanged" が含まれていません。" Explicit " を使用し、コード ビハインドで手動で " UpdateSource " を呼び出す必要があります。そうしないと、TextBox/PasswordBox がフォーカスを失ったときに TextBox/PasswordBox の値が上昇します。

そして、「 Mode=TwoWay 」を設定することを忘れないでください。

<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;
    }

このサンプルを確認してください。

于 2013-10-08T09:14:17.313 に答える
0

View と ViewModel を「リンク」して同期させるには、INotifyPropertyChanged (ViewModelBase にカプセル化) を実装する必要があります。すなわち:

private string userName;
public string UserName
{
    get { return userName; }
    set
    {
        if (value != userName)
        {
            userName = value;
            RaisePropertyChanged("UserName");
        }
    }
}
于 2013-10-08T01:36:35.977 に答える