2013-10-08 40 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"); 
     } 
    } 
}