2013-10-08 36 views
1
  • 我有一个用户名和密码框。
  • 它下面有一个按钮。
  • 当我点击那个按钮时,我想分析一下放入用户名和密码框的内容。

如何使用mvvm灯做到这一点?如何从文本框中获取文本与数据绑定propertynotifying thingy 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并尝试获得简单的单击事件并绑定到工作。这根本没有意义...... doh。谢谢你的帮助!

P.S - 对于新来者,MVVM是否太混乱了?该文件是如此..浅谈细节。没有例子:(

+1

请先查看本教程:http://blog.micic.ch/net/easy-mvvm-example-with-inotifypropertychanged-and-inotifydataerrorinfo – Tico

回答

3

查看

Windows Phone不包含“UpdateSourceTrigger = PropertyChanged”,您必须在代码后面使用“明确”并手动调用“UpdateSource”,否则TextBox/PasswordBox的值将会当TextBox/PasswordBox失去焦点时会引发。

并且不要忘记设置“模式=双向”。

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

入住这sample

+0

Windows Phone 8.1 Universal Apps模型支持'UpdateSourceTrigger = PropertyChanged'。 [简单工作版本](https://github.com/BlueWhaleSEO/.NET/blob/master/DonatasSimpleUniversal_MVVM_App/DonatasSimpleUniversal_MVVM_App/DonatasSimpleUniversal_MVVM_App.WindowsPhone/MainPage.xaml) – Donatas

0

要获得查看和视图模型“联系起来”,让它们同步,则需要执行INotifyPropertyChanged(在ViewModelBase封装),即:

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