Xamarin ListView ItemsSource 无法在 PopupPage 中绑定数据
Xamarin ListView ItemsSource cannot bind data inside PopupPage
我遇到了一个奇怪的问题。
(在此代码中,我使用 InputKit.Checkbox)
接着 this tutorial,我创建了视图、模型和视图模型,如下所示:
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 中的内容根本不显示。但是当我在 c# 代码中应用 ItemsSource 时,如:MultiListView.ItemsSource = _vm.Items;
(在代码中提交),数据出现。我想通过使用 xaml 正确地做到这一点。
此外,这很奇怪,但是字段 AllChecked
从未在模型中触发。
那么我的代码有什么问题?谁能给我解释一下?提前致谢。
一段时间后我发现了非常奇怪的结果:
我使用普通的 PopupPage
和空的 ContentView
在两行代码中初始化许多弹出页面而不是 copy/paste xaml 代码来初始化它.当我将此 class 与 ListView 一起使用并将我的 MultiselectListView
作为弹出内容时,绑定不起作用。
但是当我创建PopupPage
'from zero'时,绑定起作用了,ItemsSource
出现了。这真的很奇怪,但它起作用了。
我遇到了一个奇怪的问题。 (在此代码中,我使用 InputKit.Checkbox)
接着 this tutorial,我创建了视图、模型和视图模型,如下所示:
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 中的内容根本不显示。但是当我在 c# 代码中应用 ItemsSource 时,如:MultiListView.ItemsSource = _vm.Items;
(在代码中提交),数据出现。我想通过使用 xaml 正确地做到这一点。
此外,这很奇怪,但是字段 AllChecked
从未在模型中触发。
那么我的代码有什么问题?谁能给我解释一下?提前致谢。
一段时间后我发现了非常奇怪的结果:
我使用普通的 PopupPage
和空的 ContentView
在两行代码中初始化许多弹出页面而不是 copy/paste xaml 代码来初始化它.当我将此 class 与 ListView 一起使用并将我的 MultiselectListView
作为弹出内容时,绑定不起作用。
但是当我创建PopupPage
'from zero'时,绑定起作用了,ItemsSource
出现了。这真的很奇怪,但它起作用了。