Xamarin ListView ItemsSource не может связать данные внутри PopupPage - PullRequest
0 голосов
/ 15 мая 2019

Я застрял со странной проблемой. (В этом коде я использую InputKit.Checkbox )

Вслед за этим руководством , я создал представление, модель и модель представления следующим образом:

view.xaml:

<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:controls="clr-namespace:Plugin.InputKit.Shared.Controls;assembly=Plugin.InputKit"
             x:Class="ISSO_I.PopupTypes.MultiselectListView">
    <ContentView.Content>
        <StackLayout>
            <ListView RowHeight="70" Margin="5" ItemsSource="{Binding Items}">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <StackLayout Orientation="Horizontal">
                                <controls:CheckBox IsChecked="{Binding IsChecked}" LabelPosition="After" Margin="10"
                                                   Type="Material" Text="{Binding Body}" TextColor="Black" />
                            </StackLayout>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
            <BoxView Color="Accent" HeightRequest="1" />
            <controls:CheckBox IsChecked="{Binding Path=AllChecked}" LabelPosition="After" Margin="10" Type="Material"
                               Text="(Выбрать все)" TextColor="Black" />
            <Button Style="{StaticResource ButtonStandard}" Margin="10" Text="Применить" Clicked="ButtonConfirmClicked"/>
        </StackLayout>
    </ContentView.Content>
</ContentView>

view.xaml.cs:

public partial class MultiselectListView
    {

        private readonly MultiselectListViewModel _vm;

        public event EventHandler ApplyConstrs;

        /// <summary>
        /// Для заголовка окна
        /// </summary>
        public const string Header = "Выбранные номера конструкций";

        public MultiselectListView (ObservableCollection<MultiselectItem> items)
        {
            InitializeComponent();
            //MultiListView.ItemsSource = _vm.Items;
            BindingContext = _vm = new MultiselectListViewModel(items);
        }

        protected virtual void OnApplyConstrs()
        {
            ApplyConstrs?.Invoke(_vm.Items.Where(item => item.IsChecked).ToList(), EventArgs.Empty);
        }

        private async void ButtonConfirmClicked(object sender, EventArgs e)
        {
            OnApplyConstrs();
            await Navigation.PopAsync();
        }
    }

view_model.cs:

public class MultiselectListViewModel : INotifyPropertyChanged
    {
        /// <summary>
        /// Номера конструкций
        /// </summary>
        private ObservableCollection<MultiselectItem> _items;
        public ObservableCollection<MultiselectItem> Items
        {
            get => _items;
            set
            {
                if (_items == value) return;
                _items = value;
                OnPropertyChanged(nameof(Items));
            }
        }

        private bool _allChecked;
        public bool AllChecked
        {
            get => _allChecked;
            set
            {
                if (_allChecked == value) return;
                _allChecked = value;
                OnPropertyChanged(nameof(AllChecked));
                // Меняем все галочки
                foreach (var item in Items)
                {
                    item.IsChecked = _allChecked;
                }
            }
        }

        public MultiselectListViewModel(ObservableCollection<MultiselectItem> items)
        {
            Items = items;
        }

        #region INotify Staff

        public event PropertyChangedEventHandler PropertyChanged;

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

        #endregion

    }

и, наконец, model.cs:

public class MultiselectItem
    {

        /// <summary>
        /// Признак выбранного элемента
        /// </summary>
        public bool IsChecked { get; set; }

        /// <summary>
        /// Текст элемента
        /// </summary>
        public string Body { get; set; }
    }

Когда я использую этот код, содержимое в listView вообще не отображается. Но когда я применяю ItemsSource в коде c # вроде: MultiListView.ItemsSource = _vm.Items; (подтверждено в коде), появляются данные. Я хочу сделать это правильно, используя xaml.

Кроме того, это странно, но поле AllChecked никогда не срабатывает в модели.

Так что не так с моим кодом? Может ли кто-нибудь объяснить мне это? Заранее спасибо.

1 Ответ

0 голосов
/ 15 мая 2019

Через некоторое время я нашел очень странный результат:

Я использую общий PopupPage с пустым ContentView в нем для инициализации многих всплывающих страниц в двух строках кода, а не для копирования / вставкиXAML-код для его инициализации.Когда я использую этот класс с ListView и моим MultiselectListView в качестве всплывающего содержимого, привязка не работает.

Но когда я создал PopupPage 'с нуля', связывание сработало, ItemsSource появилось.Это действительно странно, но это сработало.

...