2016-07-14 4 views
0

Добрый день. Я создаю простое приложение Xamarin.Forms (Portable), которое позволяет мне создавать запись сотрудника и сохранять его в базе данных в Visual Studio. Все записи отображаются в ListView.Xamarin.Forms: ListView не отображается на Android

Мое приложение отлично работает, когда я запускаю его на UWP. Он отображает все созданные записи в ListView правильно.

Но когда я запускаю его на платформе Android, он не отображает никаких записей в ListView. Я даже пытался проверить веб-API, возвращает ли оно значение или нет. И я получил ценность. Смысл, проблема в Android Platform, почему она не отображает никаких записей.

У вас возникли проблемы? Как вы думаете, в чем причина этого? Что я могу сделать сейчас? Извините, я просто новичок здесь, в Xamarin. Надеюсь, ты поможешь мне. Большое спасибо.

Вот некоторые коды у меня есть:

EmployeeRecordsPage.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="XamarinFormsDemo.EmployeeRecordsPage" 
     xmlns:ViewModels="clr-namespace:XamarinFormsDemo.ViewModels;assembly=XamarinFormsDemo" 
     xmlns:controls="clr-namespace:ImageCircle.Forms.Plugin.Abstractions;assembly=ImageCircle.Forms.Plugin.Abstractions" 
     BackgroundImage="bg3.jpg" 
     Title="List of Employees"> 


    <ContentPage.BindingContext> 
    <ViewModels:MainViewModel/> 
    </ContentPage.BindingContext> 

    <StackLayout Orientation="Vertical"> 


    <ListView ItemsSource="{Binding EmployeesList}" 
     HasUnevenRows="True" 
     IsPullToRefreshEnabled="True" 
     > 
<ListView.ItemTemplate> 
    <DataTemplate> 
    <ViewCell> 
     <Grid Padding="10" RowSpacing="10" ColumnSpacing="5"> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="Auto"/> 
      <RowDefinition Height="*"/> 
     </Grid.RowDefinitions> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="Auto"/> 
      <ColumnDefinition Width="*"/> 
     </Grid.ColumnDefinitions> 

     <controls:CircleImage Source="icon.png" 
       HeightRequest="66" 
       HorizontalOptions="CenterAndExpand" 
       Aspect="AspectFill" 
       WidthRequest="66" 
       Grid.RowSpan="2" 
       /> 


     <Label Grid.Column="1" 
       Text="{Binding EMPLOYEE_NAME}" 
       TextColor="#24e97d" 
       FontSize="24"/> 



     <Label Grid.Column="1" 
       Grid.Row="1" 
       Text="{Binding EMP_NUMBER}" 
       TextColor="White" 
       FontSize="18" 
       Opacity="0.6"/> 


     <Label Grid.Column="1" 
      Grid.Row="2" 
      Text="{Binding DEPT_COMP}" 
      TextColor="White" 
      FontSize="18" 
      Opacity="0.6"/> 



      </Grid> 
     </ViewCell> 
     </DataTemplate> 
    </ListView.ItemTemplate> 

    </ListView> 


<StackLayout Orientation="Vertical" 
     Padding="30,10,30,10" 
     HeightRequest="20" 
     BackgroundColor="#24e97d" 
     VerticalOptions="Center" 
     Opacity="0.5"> 
    <Label Text="© Copyright 2016 SMESOFT.COM.PH All Rights Reserved " 
     HorizontalTextAlignment="Center" 
     VerticalOptions="Center" 
     HorizontalOptions="Center" /> 
    </StackLayout> 
    </StackLayout> 



</ContentPage> 

..

EmployeeViewModel.cs

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Linq; 
using System.Runtime.CompilerServices; 
using System.Text; 
using System.Threading.Tasks; 
using Xamarin.Forms; 
using XamarinFormsDemo.Models; 
using XamarinFormsDemo.Services; 

namespace XamarinFormsDemo.ViewModels 
{ 
    public class MainViewModel : INotifyPropertyChanged 
    { 

     private List<Employee> _employeesList; 
     private Employee _selectedEmployee = new Employee(); 




    public List<Employee> EmployeesList 
    { 
     get { return _employeesList; } 
     set 
     { 
      _employeesList = value; 
      OnPropertyChanged(); 
     } 
    } 



    public MainViewModel() 
    { 
     InitializeDataAsync(); 
    } 

    private async Task InitializeDataAsync() 
    { 
     var employeesServices = new EmployeesServices(); 

     EmployeesList = await employeesServices.GetEmployeesAsync(); 
    } 


    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) 
    { 
     var handler = PropertyChanged; 
     if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); 
    } 

    } 
} 

..

EmployeesServices.cs

using Plugin.RestClient; 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using XamarinFormsDemo.Models; 

namespace XamarinFormsDemo.Services 
{ 
    public class EmployeesServices 
    { 

    public async Task<List<Employee>> GetEmployeesAsync() 
    { 
     RestClient<Employee> restClient = new RestClient<Employee>(); 

     var employeesList = await restClient.GetAsync(); 

     return employeesList; 

     } 

    } 
} 
+1

Можете ли вы показать вам MainActivity для Android? Вы пытались поставить точку прорыва на странице форм Xamarin и проверить, не попадает ли она? – user3185569

+0

@ user3185569 Я не пробовал поставить точку останова сэр. Я еще не знаю, как это сделать. Вот мой код для MainActivity. http://pastie.org/10906729 –

+1

Проблема не выпрыгивает на меня с показанным кодом. Можете ли вы предоставить образец проекта для запуска? – therealjohn

ответ

3

Я думаю, что проблема в том, что вы не обновляя ListView после вы получите ваши детали с:

EmployeesList = await employeesServices.GetEmployeesAsync(); 

Я хотел бы предложить, используя ObservableCollection вместо список. С наблюдаемой коллекцией ListView должен автоматически обновляться, когда элементы в ObservableCollection добавляются или удаляются. Таким образом, вместо:

private List<Employee> _employeesList; 

попробовать:

private ObservableCollection<Employee> _employeesList; 

или вы можете просто присвоить ListView.ItemsSource к null, а затем обратно в List<Employee> после вы получите ваши данные:

EDIT: Как было отмечено Jaycee, следующий код для сброса ItemsSource не должен находиться в модели представления, так как модель представления не будет иметь доступа к listView. Однако верный способ обновления listView.ItemsSource. Модель просмотра просто должна позволить зрителю знать, что EmployeesList был обновлен, а затем вы можете сбросить listView.ItemsSource в код, стоящий за представлением. Это можно сделать несколькими способами, о которых я могу думать. Например, у вас может быть делегат в ViewModel, что представление может обеспечить реализацию кода для модели представления или может привести к событию, на которое может подписаться представление. В основном вам просто нужно сообщить, что нужно обновить ListViewItemsSource. Но все это можно было бы избежать, используя ObservableCollection вместо списка, как я уже отмечал ранее.

EmployeesList = await employeesServices.GetEmployeesAsync(); 
listView.ItemsSource = null; 
listView.ItemsSource = EmployeesList; 

И сделать выше, вы должны дать вашей ListView имя, которое вы можете использовать, чтобы ссылаться на него в коде. Вы можете установить это имя в XAML для ListView:

<ListView 
    ItemsSource="{Binding EmployeesList}" 
    HasUnevenRows="True" 
    IsPullToRefreshEnabled="True" 
    x:Name="listView" 
> 

Но ObservableCollection будет предпочтительным вариантом.

+0

Sir Почему я не могу получить доступ к спискуView в моей модели ViewModel, даже если я объявил его здесь: x: Name = "listView" –

+0

Он будет доступен в вашем файле кода для страницы Xaml, а не в модели представления. Я не эксперт MVVM, но, насколько я понимаю, в идеале ViewModel не должен знать ничего о представлении, так как ViewModel View потенциально может использоваться для нескольких видов. Таким образом, вы можете захотеть, чтобы ваш ViewModel увеличил событие, когда EmployeesList загружен, и ваш код представления может подписаться на это событие, чтобы он мог перезагрузить ItemsSource для listView. – jgoldberger

+0

Да, он доступен в моем коде. Итак, что вы сделали здесь, неверно: EmployeesList = ожидают сотрудниковServices.GetEmployeesAsync(); listView.ItemsSource = null; listView.ItemsSource = EmployeesList; –

Смежные вопросы