2017-04-04 68 views
0

我想使用Xamarin在xaml中創建一個簡單的登錄界面。我在MainPage中使用Entry創建一個用戶名和密碼字段,然後嘗試將它們綁定到我的LoginViewModel,在那裏我可以訪問我的connexion方法。如何在Xamarin PCL項目中進行數據綁定?

當我在應用程序後面的Mainpage代碼中定義Binding上下文時,只需關閉,我不明白爲什麼,我做錯了什麼?

MainPage.xaml中

<?xml version="1.0" encoding="utf-8" ?> 
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
      xmlns:local="clr-namespace:suivAAndroid" 
      x:Class="suivAAndroid.MainPage"> 

    <StackLayout 
     VerticalOptions="CenterAndExpand"> 
     <Image></Image> 
    <Label 
     Text="Login" 
     StyleId="lbl_login"></Label> 
    <Entry 
     StyleId="ent_login" 
     Text="{Binding Username}"></Entry> 
     <Label 
      Text="Mot de passe" 
      StyleId="ent_mdp"></Label> 
     <Entry 
      StyleId="ent_mdp" 
      Text="{Binding Password}"></Entry> 
     <Button 
      Clicked="connexion_click" 
      Text="Connexion"></Button> 
    </StackLayout> 
</ContentPage> 

MainPage.xaml.cs中

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using Xamarin.Forms; 
using Xamarin.Forms.Xaml; 

namespace suivAAndroid 
{ 

    public partial class MainPage : ContentPage 
    { 
     public MainPage() 
     { 
      InitializeComponent(); 

      BindingContext = new LoginViewModel(); // Here is where it does not work. If the line is commented out, then the application launch without stopping but because there is no binding context I cant get the user inputs. 
     } 


     private void connexion_click(object sender, EventArgs e) 
     { 
      LoginViewModel connexionBtn = new LoginViewModel(); 
      Device.BeginInvokeOnMainThread(async() => 
       { 
        await connexionBtn.Connexion(); 
       }); 
     } 
    } 
} 

LoginViewModel.cs

using suivAAndroid.Models; 
using suivAAndroid.Views; 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace suivAAndroid 
{ 
    public class LoginViewModel 
    { 
     #region propriétés 
     public string Username 
     { 
      get 
      { 
       return Username; 
      } 
      set 
      { 
       Username = value; 
      } 
     } 

     public string Password 
     { 
      get 
      { 
       return Password; 
      } 
      set 
      { 
       Password = value; 
      } 
     } 
     #endregion 

     #region constructor 
     public LoginViewModel() 
     { 

     } 
     #endregion 

     #region methodes 

     public void CreerListeVisiteurDur(List<Visiteur> uneListe) 
     { 
      Visiteur unVisiteur = new Visiteur("Clooney", "George", "cgeorge", "azerty", "rue du port", "59", "lille", new DateTime(2015/07/13)); 
      uneListe.Add(unVisiteur); 
     } 
     public async Task Connexion() 
     { 
      List<Visiteur> uneListe = new List<Visiteur>(); 
      CreerListeVisiteurDur(uneListe); 
      if (!string.IsNullOrEmpty(Username) && !string.IsNullOrEmpty(Password)) 
      { 
       foreach (Visiteur unVisiteur in uneListe) 
       { 
        string login = unVisiteur.login; 
        string pass = unVisiteur.mdp; 

        if (login == Username && pass == Password) 
        { 
         App.Current.MainPage = new CreerVisite(); 
        } 

       } 
      } 

     } 
     #endregion 
    } 
} 

回答

2

您的視圖模式升特性有無限循環:

public string Username 
    { 
     get 
     { 
      return Username; 
     } 
     set 
     { 
      Username = value; 
     } 
    } 

調用Username = value將調用setUsername這反過來又要求Username = value

另外,爲了使您的ViewModel可綁定,您必須實現INotifyPropertyChanged

如果你想要一個易於使用的框架來幫助你做到這一點,我會建議Mvvm Light

這裏是您的視圖模型應該是什麼樣子的例子:

public class MyViewModel : INotifyPropertyChanged 
{ 
    public event EventHandler<PropertyChangedEventArgs> OnPropertyChanged; 
    private string _username; 
    public string Username 
    { 
     get 
     { 
      return _username; 
     } 
     set 
     { 
      _username = value; 
      PropertyChanged?.Invoke(new PropertyChangedEventArgs("Username"); 
     } 
    } 
.... 
} 
+0

的PropertyChanged .Invoke(新PropertyChangedEventArgs( 「用戶名」);?這是什麼線做 –

+0

'PropertyChanged'是Xamarin.Forms爲了更新視圖而尋找的東西,當你設置BindingContext時,Xamarin.Forms會檢查它是否實現INotifyPropertyChanged,如果它確實,它會附加一個EventHandler。喚醒它,它更新視圖,無論你有綁定到該屬性。 – SuavePirate

1
  1. 在connexion_click你創建你的VM的新副本有沒有關係,您的BindingContext創建之前的副本。

    public partial class MainPage:ContentPage { private LoginViewModel vm;

    public MainPage() 
        { 
         InitializeComponent(); 
    
         vm = new LoginViewModel(); 
         BindingContext = vm; 
    
        } 
    
    
        private void connexion_click(object sender, EventArgs e) 
        { 
    
         Device.BeginInvokeOnMainThread(async() => 
          { 
           await vm.Connexion(); 
          }); 
        } 
    } 
    
  2. 你的虛擬機應執行INotifyPropertyChanged

  3. 虛擬機有一個遞歸吸氣

相關問題