c# - 无法在 CollectionView 中选择一个项目两次,当尝试解决时,在 Xamarin Forms 中触发事件两次
问题描述
我正在使用 MVVM 模式。我有一个CollectionView
选择时调用ViewModel中的 Command 的项目。
第一个问题是我不能两次选择一个项目。我可以有一些解决方法,让它像设置一样工作CollectionView.SelectedItem = null
。
第二个问题是,当我设置时CollectionView.SelectedItem = null
,SelectionChangedCommand
被调用了两次(第一次是为了选择一个项目,第二次是因为设置SelectedItem = null
)。这是Company Selected Name = " + SelectedCompany.Name
在 ViewModel 中打印两次。
这是我的 XAML 代码:
<CollectionView ItemsSource="{Binding CompanyListItems}" SelectedItem="{Binding SelectedCompany}"
SelectionChangedCommand="{Binding CompanySelectedCommand}"
SelectionMode="Single" SelectionChanged="SelectionChanged">
SelectionChanged="SelectionChanged">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Label Text="{Binding Name}" />
</StackLayout>
</DataTemplate>
</CollectionView>
C#代码背后:
void SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if ((sender as CollectionView).SelectedItem != null)
(sender as CollectionView).SelectedItem = null;
}
视图模型
public class CompaniesListPageViewModel : INotifyPropertyChanged
{
public CompaniesListPageViewModel()
{
CompanySelectedCommand = new Command<SelectionChangedEventArgs>(execute: (SelectionChangedEventArgs args) => CompanySelected(args));
}
public CompanyListItem SelectedCompany
{
get { return selectedCompany; }
set
{
if (value != null)
{
selectedCompany = value;
OnPropertyChanged(nameof(SelectedCompany));
}
}
}
CompanyListItem selectedCompany;
void CompanySelected(SelectionChangedEventArgs args)
{
Debug.WriteLine("Company Selected Name = " + SelectedCompany.Name);
Navigation.PushAsync(new CompanyDetailPage(SelectedCompany));
}
}
解决方案
由于您已SelectionChanged
在 Code Behind 中使用过,因此您的 xaml 中不需要SelectionChangedCommand
。
请参考以下代码,我在示例代码VerticalListSingleSelectionPage.xaml.cs上进行了测试,它在我这边工作正常。
<CollectionView ItemsSource="{Binding Monkeys}"
SelectionMode="Single"
SelectionChanged="OnCollectionViewSelectionChanged">
和后面的代码:
void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e)
{
var MyCollectionView = sender as CollectionView;
if (MyCollectionView.SelectedItem == null)
return;
UpdateSelectionData(e.PreviousSelection, e.CurrentSelection);
//clear selection
MyCollectionView.SelectedItem = null;
}
void UpdateSelectionData(IEnumerable<object> previousSelectedItems, IEnumerable<object> currentSelectedItems)
{
string previous = (previousSelectedItems.FirstOrDefault() as Monkey)?.Name;
string current = (currentSelectedItems.FirstOrDefault() as Monkey)?.Name;
Monkey currentMonkey = (currentSelectedItems.FirstOrDefault() as Monkey);
if (currentMonkey!=null) {
Navigation.PushAsync(new DetailPage(currentMonkey));
}
}
更新:
我想用 MVVM 来做。因此,我想从我的 ViewModel 类导航到另一个页面。
为此,您可以参考以下代码:
async void MonkeySelectionChangedAsync()
{
if (SelectedMonkey!=null) {
SelectedMonkeyMessage = $"Selection {selectionCount}: {SelectedMonkey.Name}";
OnPropertyChanged("SelectedMonkeyMessage");
selectionCount++;
System.Diagnostics.Debug.WriteLine("-----------> " + SelectedMonkey.Name);
await Application.Current.MainPage.Navigation.PushAsync(new DetailPage(SelectedMonkey));
}
}
你首先需要selectedMonkey
在null
你的视图模型的构造函数中初始化。
public MonkeysViewModel()
{
selectedMonkey = null;
// other code
}
之后,分配SelectedItem
给null
函数OnAppearing
:
protected override void OnAppearing()
{
base.OnAppearing();
//mCollectionView is the `x:Name` of your `CollectionView`
mCollectionView.SelectedItem = null;
}
而xaml是:
<CollectionView
x:Name="mCollectionView"
ItemsSource="{Binding Monkeys}"
SelectionMode="Single"
SelectedItem="{Binding SelectedMonkey}"
SelectionChangedCommand="{Binding MonkeySelectionChangedCommand}"
>
注意:您可以根据上面的代码修改您的代码。
推荐阅读
- java - JPA 没有为实体生成 ID
- docker - Docker Compose 文件:从另一个文件引用环境变量
- json - 使用 API 在 netsuite 中创建 salesOrder 的示例 JSON 格式
- python - 如何在 SerializerMethodField() 使用多个查询集优化 django-rest-framework 序列化器
- django - 如何在 StackedInline Django 中显示额外的动态字段以及所有模型字段
- c++ - 二维数组——“初始化器值太多”警告/错误
- c# - 检测到带有父母标签的孩子
- php - 通过 Redis 的 Laravel 队列:local.ERROR:连接到 127.0.0.1:6379 时出现读取错误
- r - R:将 summary()$coef 转换为数值向量
- azure - 无法从基于 Java 的 Rest API 访问 SharePoint 图形 API