问题
我正在尝试使用 CollectionView
和 MvvM
进行多项选择。 ( official docs 并没有很好地区分正常的代码隐藏和 MVVM,对于我们这些菜鸟来说,这是很痛苦的。
我可以进行单选,但无法实现多选。
我将展示我的单选工作代码,并讨论如何使其适用于多选。也许有人比我知道更多?
单选
这是单选的工作代码:
将 Person
类型的 ObservableCollection
传递给 ModelView。声明一个 Person
实例,它将成为“选定的对象”。
namespace Sandbox.ViewModel;
[QueryProperty("Persons", "Persons")]
public partial class SelectPageViewModel : ObservableObject
{
[ObservableProperty]
private ObservableCollection<Person> persons;
[ObservableProperty]
private Person selectedPerson;
public SelectPageViewModel()
{
Persons = new();
}
}
在 View 中,创建一个 CollectionView
并对其属性做出一些好的猜测:
<Grid>
<Label Text="Select from List"/>
<CollectionView ItemsSource="{Binding Persons}"
SelectionMode="Single"
SelectedItem="{Binding SelectedPerson}"
SelectionChangedCommand="{Binding SelectionChangedCommand}">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="model:Person">
<Grid>
<Label Text="{Binding Name}"/>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</Grid>
回到 ViewModel 中,SelectionChanged
命令:如果用户对他们的 SelectedPerson
选择感到满意,我会将其传回其来源的页面,否则我取消选择并返回:
[RelayCommand]
private async Task SelectionChanged()
{
bool keepSelection = await App.Current.MainPage.DisplayAlert(SelectedPerson.Name, "Keep this selection?", "Yes", "No");
if (keepSelection)
{
Dictionary<string, object> throwParam = new()
{
{ "SelectedPerson", SelectedPerson }
};
await Shell.Current.GoToAsync("..", throwParam);
}
// else clear the selection and return
SelectedPerson = null;
return;
}
多项选择
经过一番努力,这里是工作代码。非常重要的事情:请注意用于绑定(bind)到集合的 ObservableCollection
的类型(提示,它是 Object
)。
另一个编辑(我当前的代码)
我当前的代码与上面的代码相同,但我将总共显示 ViewModel 和 View,以及应该填充的列表的屏幕截图。
View 模型:
namespace Sandbox.ViewModel;
[QueryProperty("Persons","Persons")]
public partial class SelectPageViewModel : ObservableObject
{
[ObservableProperty]
private ObservableCollection<Person> persons;
[ObservableProperty]
private ObservableCollection<Object> selectedPersons;
[ObservableProperty]
private Person selectedPerson;
public SelectPageViewModel()
{
Persons = new();
SelectedPersons = new();
}
[RelayCommand]
private void SelectionChanged()
{
// every time something is selected, the object is added to SelectedPersons automagically.
int a = SelectedPersons.Count; // will +1 every time
}
}
查看:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:viewmodel="clr-namespace:Sandbox.ViewModel"
xmlns:model="clr-namespace:Sandbox.Model"
x:DataType="viewmodel:SelectPageViewModel"
x:Class="Sandbox.View.SelectPage"
Title="SelectPage">
<Grid RowDefinitions="Auto,Auto" Padding="10">
<Label Grid.Row="0"
Text="Select from List"
FontSize="Large"
FontAttributes="Bold" />
<CollectionView Grid.Row="1"
ItemsSource="{Binding Persons}"
SelectionMode="Multiple"
SelectedItems="{Binding SelectedPersons, Mode=TwoWay}"
SelectionChangedCommand="{Binding SelectionChangedCommand}">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="model:Person">
<Grid Padding="10">
<Label Text="{Binding Name}"
FontSize="Medium" />
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</Grid>
</ContentPage>
最佳答案
在虚拟机中创建一个属性(请注意,它需要是对象的集合(请参阅 this question)
[ObservableProperty]
private ObservableCollection<Person> persons;
[ObservableProperty]
private ObservableCollection<object> selectedPersons;
初始化它们
public SelectPageViewModel()
{
Persons = new();
SelectedPersons = new();
}
然后将您的CollectionView
绑定(bind)到它
<CollectionView ItemsSource="{Binding Persons}"
SelectionMode="Multiple"
SelectedItems="{Binding SelectedPersons}"
SelectionChangedCommand="{Binding SelectionChangedCommand}">
如果用户选择 3 行,这 3 个对象将包含在 SelectedPersons
中。 SelectedPersons
将是您的 ItemsSource
Persons
[RelayCommand]
private void SelectionChanged()
{
foreach(var p in SelectedPersons)
{
if (p is Person person)
{
Console.WriteLine($"{person.Name} is selected");
}
}
}
[ObservableProperty]
private ObservableCollection<Person> persons;
[ObservableProperty]
private ObservableCollection<object> selectedPersons
关于c# - .Net MAUI : How to select single and multiple items using MVVM and CollectionView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77208180/