Привязка наблюдаемой коллекции Xamarin Forms к списку не будет - PullRequest
0 голосов
/ 30 января 2019

Новичок в кодировании.Возникли проблемы с моим представлением, которое не связывает мою наблюдаемую коллекцию типа UserModel.Данные отображаются с помощью Debug.WriteLine, они просто не будут привязываться к представлению.Вот мой код.

View - привязка, установленная ItemsSource.

<?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:ic="clr-namespace:ImageCircle.Forms.Plugin.Abstractions;assembly=ImageCircle.Forms.Plugin"
         x:Class="Monger.View.HomePage">
<ContentPage.Content>
    <StackLayout  Orientation="Vertical">
        <StackLayout Orientation="Horizontal" Padding="25,0,15,10" Margin="0,10,0,0">
                <StackLayout Orientation="Horizontal" Padding="10,0,5,0">
                    <ic:CircleImage HeightRequest="60" WidthRequest="60" Aspect="AspectFill" Source="http://placekitten.com/400/300" HorizontalOptions="Start"/>
                    <Label Margin="9,0,0,0" VerticalOptions="CenterAndExpand" HorizontalOptions="EndAndExpand" FontSize="30" TextColor="#A3D1F5" Text="{Binding DeviceEui}"/>
                </StackLayout>
            </StackLayout>
            <BoxView HeightRequest="1" BackgroundColor="Black" HorizontalOptions="FillAndExpand" />
        <StackLayout Padding="20,0,20,0" Margin="0,10,0,0">
            <ListView x:Name="DeviceListView" SelectedItem="{Binding DeviceSelected}" ItemSelected="DeviceList_ItemSelected" ItemsSource="{Binding DevicesDisplay}"  Header="Devices" SeparatorColor="#A3D1F5">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <TextCell Text="{Binding DeviceEui}"/>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </StackLayout>
        <StackLayout Margin="0,0,0,30" Padding="20,0,20,0">
            <Button Text="Add Device" BorderRadius = "20" BackgroundColor="#A3D1F5" Command="{Binding AddDeviceCommand}"/>
        </StackLayout>
    </StackLayout>
</ContentPage.Content>
</ContentPage>

View Code Behind - будет постепенно избавляться от большей части кода, чтобы присоединиться к MVVM.В настоящий момент он просто проверяет разрешения и, если все в порядке, запускает LoadDevicesCommand, устанавливает контекст привязки для HomePageViewModel и инициализирует новый HomePageViewModel.

namespace Monger.View
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class HomePage : ContentPage
{
    public HomePage ()
    {

        InitializeComponent ();
        ViewModel = new HomePageViewModel(new PageService());
    }


    protected async override void OnAppearing()
    {

        try
        {
            var status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Location);
            if (status != PermissionStatus.Granted)
            {
                if (await CrossPermissions.Current.ShouldShowRequestPermissionRationaleAsync(Permission.Location))
                {
                    await DisplayAlert("Need location", "We need your location to display where you are on the map.", "OK");
                }

                var results = await CrossPermissions.Current.RequestPermissionsAsync(Permission.Location);
                //Best practice to always check that the key exists
                if (results.ContainsKey(Permission.Location))
                    status = results[Permission.Location];
            }

            if (status == PermissionStatus.Granted)
            {
                ViewModel.LoadDevicesCommand.Execute(this);
                base.OnAppearing();
            }
            else if (status != PermissionStatus.Unknown)
            {
                await DisplayAlert("Location Denied", "Can not continue, try again.", "OK");
            }
        }
        catch (Exception)
        { };

    }


    private HomePageViewModel ViewModel
    {
        get { return BindingContext as HomePageViewModel; }
        set { BindingContext = value; }
    }

    private void DeviceList_ItemSelected(object sender, SelectedItemChangedEventArgs e)
    {
        ViewModel.DeviceSelectedCommand.Execute(e.SelectedItem);
    }
}

}

Просмотр модели - впервые с использованием Sqlite, создание таблицыа затем захватывает таблицу при запуске, если она еще не существует.Настройка действия контекста на будущее, но не может заставить работать привязки.Добавить устройство добавляет объект UserModel, вставляет его в базу данных sql, а затем добавляет его в наблюдаемую коллекцию типа UserModel.При изменении свойства должен был быть запущен для обновления привязок.

namespace Monger.ViewModel
{
class HomePageViewModel : BaseViewModel
{
    private HttpClient _client = new HttpClient();
    private ObservableCollection<UserModel> _devices;
    private readonly IPageService _pageService;
    private UserModel _deviceSelected;
    public UserModel DeviceSelected { get { return _deviceSelected; } set { SetValue(ref _deviceSelected, value); } }

    private List<UserModel> _userDevices;
    private SQLiteAsyncConnection _connection;

    public ObservableCollection<UserModel> DevicesDisplay
    {
        get { return _devices; }
        set { SetValue(ref _devices, value); }
    }

    public String _deviceEui;

    public ICommand DeviceSelectedCommand { get; private set; } 
    public ICommand AddDeviceCommand { get; private set; }
    public ICommand LoadDevicesCommand { get; private set; }

    public HomePageViewModel(IPageService pageService)
    {
       _connection = DependencyService.Get<ISQLiteDb>().GetConnection();
        _pageService = pageService;
        LoadDevicesCommand = new Command(GetSqlConnection);
        AddDeviceCommand = new Command(AddDevice);
        DeviceSelectedCommand = new Command<UserModel>(async vm => await OnDeviceSelected(vm));
    }

    private async void GetSqlConnection() {
        await _connection.CreateTableAsync<UserModel>();
        _userDevices = await _connection.Table<UserModel>().ToListAsync();
        DevicesDisplay = new ObservableCollection<UserModel>(_userDevices);
    }


    private async Task OnDeviceSelected(UserModel Selected)
    {
        if (Selected == null)
            return;
        DeviceSelected = null;

        _deviceEui = Selected.DeviceEui;

        await _pageService.PushModalAsync(new MapPage(_deviceEui));
    }

    public async void AddDevice() {
        var userdevice = new UserModel { DeviceEui = "0000000000000777", DeviceName = "Ryans Laptop", DeviceCategory = "phone.png" };
        await _connection.InsertAsync(userdevice);
        DevicesDisplay.Add(userdevice);
        Debug.WriteLine(_devices[0].DeviceCategory);
    }
}

}

BaseViewModel - Это из учебника по коду с Mosh

namespace Monger.ViewModel
{
public class BaseViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

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

    protected void SetValue<T>(ref T backingField, T Value, [CallerMemberName] string propertyName = null)
    {
        if (EqualityComparer<T>.Default.Equals(backingField, Value))
            return;
        backingField = Value;
        OnPropertyChanged(propertyName);
    }
}
}

Ответы [ 2 ]

0 голосов
/ 31 января 2019

Решено: установите для свойства hasUnevenRows значение true при просмотре списка и отображаемых данных.

0 голосов
/ 30 января 2019

Вы не привязываете источник элементов списка просмотра

<ListView x:Name="DeviceListView" ItemsSource="{Binding DevicesDisplay}"   SelectedItem="{Binding DeviceSelected}" ItemSelected="DeviceList_ItemSelected" Header="Devices" SeparatorColor="#A3D1F5">
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...