Xamarin列表查看SelectedItem ViewModel绑定

时间:2016-12-09 11:07:49

标签: c# xamarin

使用Visual Studio 2015 proff,

我的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”背后的代码上的Binding有关?但我不确定。

2 个答案:

答案 0 :(得分:1)

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

            if (e.SelectedItem == null) return; 

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

这很有用,必须将页面设置为App.cs中的导航包,然后将此事件处理程序应用于OnAppearing方法。

答案 1 :(得分:1)

虽然您所拥有的可能会有所作为,但我会建议进行一些调整。

无需在构造函数和BindingContext中设置OnAppearing()。只需在代码隐藏中设置LoginViewModel类级私有属性,并将其分配给构造函数中的BindingContext。然后在GetEmployees()中拨打OnAppearing()

此外,您应该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>