2016-12-09 8 views
2

mit Visual Studio 2015 proff,Xamarin Listenansicht SelectedItem Ansichtsmodell Bindung

Meine LoginViewModel Klasse (Portable Klassenbibliothek)

public class LoginViewModel : INotifyPropertyChanged, INotifyCollectionChanged 
{ 
    LoginPage page; 
    private ObservableCollection<Employees> _employeeList; 
    private string _loginName; 

    public ObservableCollection<Employees> EmployeeList 
    { 
     get { return _employeeList; } 
     set 
     { 
      _employeeList = value; 
      OnPropertyChanged(); 
      OnCollectionChanged(NotifyCollectionChangedAction.Reset); 
     } 
    } 

    public string LoginName 
    { 
     get { return _loginName; } 
     set 
     { 
      _loginName = value; 
      if (_loginName != null) 
      { 
       OnPropertyChanged(); 
      } 
     } 
    } 

    public LoginViewModel(LoginPage parent) 
    { 
     page = parent; 
    } 

    public async void GetEmployees() 
    { 
     var loginService = new LoginService(); 
     EmployeeList = await loginService.GetEmployeesAsync(); 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    public event NotifyCollectionChangedEventHandler CollectionChanged; 
    protected virtual void OnCollectionChanged(NotifyCollectionChangedAction action) 
    { 
     CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(action)); 
    } 

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) 
    { 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 

    } 
} 

Mein LoginPage.xaml (Portable Klassenbibliothek)

<?xml version="1.0" encoding="utf-8" ?> 
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
     xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
     x:Class="ScannerApp.Views.LoginPage" 
     xmlns:ViewModels="clr-namespace:ScannerApp.ViewModels;assembly=ScannerApp"> 
<StackLayout Orientation="Vertical"> 

<Label Text="Please Login" 
     VerticalOptions="Start" 
     HorizontalTextAlignment="Center" 
     IsVisible="true" 
     FontSize="Large" 
     FontAttributes="Bold" /> 

<ListView x:Name="mylist" ItemsSource="{Binding EmployeeList}" 
     HasUnevenRows="True" SelectedItem="{Binding LoginName}"> 
    <ListView.ItemTemplate> 
    <DataTemplate> 
     <ViewCell> 
     <StackLayout Orientation="Vertical" Padding="12,6"> 
      <Label Text="{Binding Name}"/> 
     </StackLayout> 
     </ViewCell> 
    </DataTemplate> 
    </ListView.ItemTemplate> 
</ListView> 

Meine LoginPage.xaml.cs Klasse (Portable Klassenbibliothek)

public partial class LoginPage : ContentPage 
{ 
    public LoginPage() 
    { 
     InitializeComponent(); 
     BindingContext = new LoginViewModel(this); 
    } 

    protected override void OnAppearing() 
    { 
     base.OnAppearing(); 
     LoginViewModel model = new LoginViewModel(this); 
     model.GetEmployees(); 
     BindingContext = model; 
    } 

    public ListView MyList 
    { 
     get 
     { 
      return mylist; 
     } 
    } 
} 

Frage

ich eine Liste von Mitarbeitern bekommen, die Liste auf dem vorderen Ende macht diese . Der Benutzer wählt dann einen Namen aus der Liste. An dieser Stelle möchte ich dies erkennen und dann zu meiner anderen Seite navigieren. Momentan ist meine Eigenschaft nicht betroffen, ich frage mich, ob das etwas mit meiner Bindung am Code hinter "OnAppearing" zu tun hat? aber ich bin mir nicht sicher.

Antwort

1

Während was Sie haben, gibt es ein paar Verbesserungen, die ich vorschlagen würde.

Keine Notwendigkeit, Ihre BindingContext in Ihrem Konstruktor und in OnAppearing() zu setzen. Machen Sie einfach Ihre LoginViewModel eine private Eigenschaft auf Klassenebene in Ihrem Code-Behind und weisen Sie sie nur Ihrem BindingContext in Ihrem Konstruktor zu. Dann rufen Sie GetEmployees() in OnAppearing().

Auch sollten Sie GetEmployees() eine Task zurückgeben, um so weit wie möglich in der Kette zu warten.

Ansichtsmodell:

.... 

public async Task GetEmployees() 
    { 
     var loginService = new LoginService(); 
     EmployeeList = await loginService.GetEmployeesAsync(); 
    } 

.... 

-Code-behind:

public partial class LoginPage : ContentPage 
{ 
    private LoginViewModel _model; 

    public LoginPage() 
    { 
     InitializeComponent(); 
     BindingContext = _model = new LoginViewModel(this); 
    } 

    protected override async void OnAppearing() //Notice I changed this to async and can now await the GetEmployees() call 
    { 
     base.OnAppearing(); 
     await _model.GetEmployees(); 
    } 

    public ListView MyList 
    { 
     get 
     { 
      return mylist; 
     } 
    } 

    private async void OnItemSelected(object sender, SelectedItemChangedEventArgs e) { 
     if (e.SelectedItem == null) return; 

     await Navigation.PushAsync(new MenuPage()); 
    } 
} 

XAML:

<!-- Adding OnItemSelected in XAML below --> 
<ListView x:Name="mylist" 
      ItemsSource="{Binding EmployeeList}" 
      HasUnevenRows="True" 
      SelectedItem="{Binding LoginName}" 
      ItemSelected="OnItemSelected"> 
    <ListView.ItemTemplate> 
    <DataTemplate> 
     <ViewCell> 
     <StackLayout Orientation="Vertical" Padding="12,6"> 
      <Label Text="{Binding Name}"/> 
     </StackLayout> 
     </ViewCell> 
    </DataTemplate> 
    </ListView.ItemTemplate> 
</ListView> 
+1

vielen Dank für den Code aufzuräumen, es krank einen Test nach dem Wochenende geben – lemunk

1
mylist.ItemSelected += async (sender, e) => { 

      if (e.SelectedItem == null) return; 

      await Navigation.PushAsync(new MenuPage()); 
}; 

Dies funktioniert, hatten die Seite eine nav Folie im App.cs zu setzen, dann gilt diese Event-Handler auf die OnAppearing Methode.