无法在 iOS 的 Xamarin.Forms 的 CollectionView 中重新选择之前选择的项目
Cant reselect previous selected item in CollectionView in Xamarin.Forms on iOS
TLDR
CollectionView 在 iOS 中损坏,无法在线找到任何解决方案。 Google fu 或只是没有看到答案。
问题
我有一个 CollectionView(我们称之为 A),其中包含的项目只是字符串值,用于在不同的 CollectionView(我们称之为 B)上进行过滤,其中包含 selectCollectionView A 中过滤选项的结果.
我在 CollectionView A 中有 3 个不同的筛选选项:“全部”、“靠近你”、“在线”。
问题是在 iOS 上,当我 select 例如第一次在页面上的 CollectionView A 中过滤选项“All”时,它会进行过滤并在 CollectionView B 中显示结果,例如,当我在 CollectionView A 中选择过滤选项“在线”时,它会过滤并在 CollectionView B 中显示结果。
但是当我在 CollectionView A 中第二次选择过滤选项“全部”时,它没有响应,没有事件触发,没有命令运行,也没有被禁用。它只是显示,但我不能用它做任何事情。
预期结果
可以重新select iOS 上的前一项,在Android 没问题。
实际结果
无法重新select iOS 上的上一个项目,需要返回堆栈中的上一页,然后导航回页面以重置过滤。
xaml 标记
如上所述,这是 CollectionView A 的 xaml 标记,唯一包含要过滤的字符串值。
<CollectionView ItemsSource="{Binding FilterLocations}"
Grid.Row="2"
SelectedItem="{Binding SelectedFilterLocation}"
SelectionMode="Single"
HeightRequest="50">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Horizontal"
ItemSpacing="10" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="x:String">
<StackLayout xct:TouchEffect.NativeAnimation="True">
<Frame BorderColor="{StaticResource BorderColor}"
x:Name="subCategoryFrame"
Padding="14, 10">
<Label Text="{Binding .}"
x:Name="subCategoryName"
FontFamily="{StaticResource FontPoppinsLight}"
TextColor="{StaticResource PrimaryAlt}" />
</Frame>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
<CollectionView.Header>
<BoxView WidthRequest="0"
HeightRequest="1"
BackgroundColor="Transparent" />
</CollectionView.Header>
<CollectionView.Footer>
<BoxView WidthRequest="{StaticResource NormalSpacingDouble}"
HeightRequest="1"
BackgroundColor="Transparent" />
</CollectionView.Footer>
</CollectionView>
CollectionView A 在 SelectionMode:Single 中,SelectedItem 绑定到其绑定的 ViewModel 上的 ICommand。在 ViewModel 中,CollectionView A 中的项目的 selection 将触发 CollectionView B 中的过滤
到目前为止我做了什么
我的设置是,如果 CollectionView A 中的某个项目被禁用,它会变成红色,但不会变成红色。
我曾尝试在后面的代码中添加一个事件,尝试将 SelectedItem 设置为 null,但该事件被触发并使所有事件发生两次,一次用于 select 显示屏幕上的项目第二个用于更改后面代码中的 SelectedItem。
代码:
private void CollectionView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (Device.RuntimePlatform == Device.iOS)
{
var collectionView = sender as CollectionView;
if (collectionView == null) return;
if (collectionView.SelectedItem != null)
{
collectionView.SelectedItem = null;
}
}
}
(我知道在 Code Behind 中做非设计逻辑的逻辑内容是一个很大的禁忌,但由于时间压力,我需要解决这个问题或快速修复。)
对不起文字墙
使用 TapGestureRecognizer
.
下面,MyItemCommand
是在MyViewModel
中定义的,{Binding .}
是指在ItemsSource
中选择的项目。
<DataTemplate ...>
<StackLayout>
<StackLayout.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Source={RelativeSource AncestorType={x:Type vm:MyViewModel}},
Path=MyItemCommand}"
CommandParameter="{Binding .}"/>
</StackLayout.GestureRecognizers>
...
首先将collection view绑定到事件selectionchange中。
<CollectionView ItemsSource="{Binding FilterLocations}"
Grid.Row="2"
SelectedItem="{Binding SelectedFilterLocation}"
SelectionMode="Single"
HeightRequest="50"
SelectionChanged="collection_SelectionChanged">
然后在事件中将所选项目置为空。
private async void collection_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
try
{
var Sender = sender as CollectionView;
if (Sender.SelectedItem == null)
return;
Sender.SelectedItem = null;
}
catch (Exception ex)
{
}
}
TLDR
CollectionView 在 iOS 中损坏,无法在线找到任何解决方案。 Google fu 或只是没有看到答案。
问题
我有一个 CollectionView(我们称之为 A),其中包含的项目只是字符串值,用于在不同的 CollectionView(我们称之为 B)上进行过滤,其中包含 selectCollectionView A 中过滤选项的结果.
我在 CollectionView A 中有 3 个不同的筛选选项:“全部”、“靠近你”、“在线”。
问题是在 iOS 上,当我 select 例如第一次在页面上的 CollectionView A 中过滤选项“All”时,它会进行过滤并在 CollectionView B 中显示结果,例如,当我在 CollectionView A 中选择过滤选项“在线”时,它会过滤并在 CollectionView B 中显示结果。
但是当我在 CollectionView A 中第二次选择过滤选项“全部”时,它没有响应,没有事件触发,没有命令运行,也没有被禁用。它只是显示,但我不能用它做任何事情。
预期结果
可以重新select iOS 上的前一项,在Android 没问题。
实际结果
无法重新select iOS 上的上一个项目,需要返回堆栈中的上一页,然后导航回页面以重置过滤。
xaml 标记
如上所述,这是 CollectionView A 的 xaml 标记,唯一包含要过滤的字符串值。
<CollectionView ItemsSource="{Binding FilterLocations}"
Grid.Row="2"
SelectedItem="{Binding SelectedFilterLocation}"
SelectionMode="Single"
HeightRequest="50">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Horizontal"
ItemSpacing="10" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="x:String">
<StackLayout xct:TouchEffect.NativeAnimation="True">
<Frame BorderColor="{StaticResource BorderColor}"
x:Name="subCategoryFrame"
Padding="14, 10">
<Label Text="{Binding .}"
x:Name="subCategoryName"
FontFamily="{StaticResource FontPoppinsLight}"
TextColor="{StaticResource PrimaryAlt}" />
</Frame>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
<CollectionView.Header>
<BoxView WidthRequest="0"
HeightRequest="1"
BackgroundColor="Transparent" />
</CollectionView.Header>
<CollectionView.Footer>
<BoxView WidthRequest="{StaticResource NormalSpacingDouble}"
HeightRequest="1"
BackgroundColor="Transparent" />
</CollectionView.Footer>
</CollectionView>
CollectionView A 在 SelectionMode:Single 中,SelectedItem 绑定到其绑定的 ViewModel 上的 ICommand。在 ViewModel 中,CollectionView A 中的项目的 selection 将触发 CollectionView B 中的过滤
到目前为止我做了什么
我的设置是,如果 CollectionView A 中的某个项目被禁用,它会变成红色,但不会变成红色。
我曾尝试在后面的代码中添加一个事件,尝试将 SelectedItem 设置为 null,但该事件被触发并使所有事件发生两次,一次用于 select 显示屏幕上的项目第二个用于更改后面代码中的 SelectedItem。
代码:
private void CollectionView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (Device.RuntimePlatform == Device.iOS)
{
var collectionView = sender as CollectionView;
if (collectionView == null) return;
if (collectionView.SelectedItem != null)
{
collectionView.SelectedItem = null;
}
}
}
(我知道在 Code Behind 中做非设计逻辑的逻辑内容是一个很大的禁忌,但由于时间压力,我需要解决这个问题或快速修复。)
对不起文字墙
使用 TapGestureRecognizer
.
下面,MyItemCommand
是在MyViewModel
中定义的,{Binding .}
是指在ItemsSource
中选择的项目。
<DataTemplate ...>
<StackLayout>
<StackLayout.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Source={RelativeSource AncestorType={x:Type vm:MyViewModel}},
Path=MyItemCommand}"
CommandParameter="{Binding .}"/>
</StackLayout.GestureRecognizers>
...
首先将collection view绑定到事件selectionchange中。
<CollectionView ItemsSource="{Binding FilterLocations}"
Grid.Row="2"
SelectedItem="{Binding SelectedFilterLocation}"
SelectionMode="Single"
HeightRequest="50"
SelectionChanged="collection_SelectionChanged">
然后在事件中将所选项目置为空。
private async void collection_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
try
{
var Sender = sender as CollectionView;
if (Sender.SelectedItem == null)
return;
Sender.SelectedItem = null;
}
catch (Exception ex)
{
}
}