2016-12-09 49 views
2

使用Visual Studio 2015年PROFF,Xamarin列表視圖的SelectedItem視圖模型結合

我LoginViewModel類(便攜式類庫)

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

    } 
} 

我LoginPage.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" 
     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> 

我LoginPage.xaml.cs類(便攜式類庫)

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

問題

我得到員工的名單,在前端列表呈現此。用戶然後從列表中選擇一個名稱,在這一點上,我想檢測這個,然後導航到我的不同頁面。 目前我的財產沒有被擊中,我想知道這是否與我在「OnAppearing」背後的代碼綁定有關?但我不確定。

回答

1

雖然你有可能工作有一些調整,我會建議。

無需在您的構造函數和OnAppearing()中設置您的BindingContext。只需將您的LoginViewModel設置爲代碼隱藏級別的私有屬性,並只將其分配給您的構造函數中的BindingContext。然後在OnAppearing()中撥打GetEmployees()

此外,你應該讓GetEmployees()返回一個Task,以等待儘可能遠的鏈。

視圖模型:

.... 

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

.... 

代碼隱藏:

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

感謝很多的代碼清理,生病給它一個測試周末後 – lemunk

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

      if (e.SelectedItem == null) return; 

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

這工作,不得不把頁面設置爲在App.cs一個導航包,那麼此事件處理程序適用於OnAppearing方法。