【问题标题】:Observable collection binding to list view won't showObservable 集合绑定到列表视图不会显示
【发布时间】:2019-06-23 17:47:09
【问题描述】:

我的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,创建一个表,然后在启动时抓取该表(如果它不存在)。为将来设置上下文操作,但无法使绑定起作用。 Add Device 添加一个UserModel 对象,将其插入到sql 数据库中,然后将其添加到UserModel 类型的Observable Collection 中。应该已触发 On Property Changed 以更新绑定。

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

【问题讨论】:

  • ItemsSource="{Binding DevicesDisplay}"
  • 抱歉,在玩的时候忘记加回来了。现在将更新帖子。还是不绑定????
  • 我要补充一点,如果你是初学者,你会尝试做很多相当复杂的事情。您可以尝试从简单的开始 - 一个带有单个 TextCell 的 ListView 和一个直接在代码中分配的 ItemsSource。让它工作,然后通过添加更复杂的 ViewCell、ViewModel、数据库访问等来迭代地增加复杂性。
  • 谢谢你,我现在试试简单版!

标签: c# xamarin data-binding xamarin.forms binding


【解决方案1】:

您没有绑定 Listview 的 ItemsSource

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

【讨论】:

  • 抱歉,在玩的时候忘记加回来了。现在将更新帖子。还是不绑定?
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2014-03-21
    • 1970-01-01
    • 2016-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-08
    相关资源
    最近更新 更多