到列表视图的可观察的集合绑定不会显示

问题描述 投票:0回答:2

我在View上遇到了麻烦,它不会绑定我的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>

查看后面的代码-将慢慢摆脱这里的大部分代码,以使它们成为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的Observable集合中。在属性更改时,应该已触发更新绑定。

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);
        }
    }
}
c# xamarin data-binding xamarin.forms binding
2个回答
1
投票

您没有绑定Listview的ItemsSource

<ListView x:Name="DeviceListView" ItemsSource="{Binding DevicesDisplay}"   SelectedItem="{Binding DeviceSelected}" ItemSelected="DeviceList_ItemSelected" Header="Devices" SeparatorColor="#A3D1F5">

0
投票

已解决:在列表视图和显示的数据上将hasUnevenRows设置为true。

© www.soinside.com 2019 - 2024. All rights reserved.