Xamarin.forms Xamarin forms Swipe视图在集合视图中,即使在条目字段中单击,也会激发选定项
我在数据模板中有一个带有滑动视图的集合视图。在数据模板中,我有一个条目和一个选择器。每当我在输入字段中单击时,键盘就会出现,并选择EdItem事件激发。对于单元格,这是第一次发生。之后,这种行为就消失了。有关行为,请参见下面的gif 我的XAML是这样的Xamarin.forms Xamarin forms Swipe视图在集合视图中,即使在条目字段中单击,也会激发选定项,xamarin.forms,Xamarin.forms,我在数据模板中有一个带有滑动视图的集合视图。在数据模板中,我有一个条目和一个选择器。每当我在输入字段中单击时,键盘就会出现,并选择EdItem事件激发。对于单元格,这是第一次发生。之后,这种行为就消失了。有关行为,请参见下面的gif 我的XAML是这样的 <CollectionView SelectionMode="Single" ItemsSource="{Binding Pro
<CollectionView
SelectionMode="Single"
ItemsSource="{Binding Products}"
SelectedItem="{Binding BindingContext.SelectedProduct, Source={x:Reference ProductList}}"
IsVisible="{Binding Products.Count, Converter={StaticResource CountToBoolConverter}}">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout>
<SwipeView>
<SwipeView.LeftItems>
<SwipeItems>
<!-- Item History button -->
<SwipeItem
Text="History"
BackgroundColor="{StaticResource ColorSecondary}"
Command="{Binding BindingContext.HistoryBtnCommand, Source={x:Reference ProductList}}"
CommandParameter="{Binding .}"
IsVisible="{Binding ShowProductHistory}" />
<SwipeItem
Text="Add to Profile"
BackgroundColor="{StaticResource ColorPrimary}"
Command="{Binding BindingContext.HistoryBtnCommand, Source={x:Reference ProductList}}"
CommandParameter="{Binding .}"
IsVisible="{Binding ShowAddItemToProfileButton}" />
</SwipeItems>
</SwipeView.LeftItems>
<SwipeView.RightItems>
<SwipeItems>
<!-- Item History button -->
<SwipeItem
Text="Delete"
BackgroundColor="{StaticResource ColorDanger}"
Command="{Binding BindingContext.HistoryBtnCommand, Source={x:Reference ProductList}}"
CommandParameter="{Binding .}"
IsVisible="{Binding ShowItemDeleteButton}" />
</SwipeItems>
</SwipeView.RightItems>
<!--Other elements not added -->
<StackLayout
Orientation="Horizontal"
VerticalOptions="Center"
IsVisible="{Binding ShowAddToCartBtn}">
<Entry
Placeholder="Quantity"
Keyboard="Numeric"
Text="{Binding EnteredQuantity, Mode=TwoWay}"
/>
<Label
Text="{Binding Units}"
VerticalOptions="Center"
IsVisible="{Binding ShowBaseUnit}" />
<Picker
Title="Select an unit"
ItemsSource="{Binding AlternateUnitOptions}"
SelectedItem="{Binding SelectedUnit }"
IsVisible="{Binding ShowAlternateUnit }"
ItemDisplayBinding="{Binding Text}"
/>
</StackLayout>
</SwipeView>
</StackLayout>
如上所示,单击输入字段将首次进入新屏幕。当我返回并再次单击输入字段时,就没有问题了
为了更好地澄清,我注释掉了SwipeView、SwipeView.LeftItems和rightItems并尝试了。这个计划没有问题。您可以看到下面的演示
你知道我为什么会有这种行为吗
多谢各位
----------------视图模型中页面导航的更新-------------------------------
private Models.Product selectedProduct;
public Models.Product SelectedProduct
{
get => selectedProduct;
set
{
SetProperty(ref selectedProduct, value);
if (selectedProduct != null)
{
OnProductItemSelected(value);
}
}
}
private void OnProductItemSelected(Models.Product selProduct)
{
if (selProduct is null) return;
navigationService.NavigateToAsync<ProductDetailPageViewModel>(selProduct);
}
私人型号。产品选择产品;
公共型号。产品选择产品
{
get=>selectedProduct;
设置
{
SetProperty(参考selectedProduct,值);
如果(selectedProduct!=null)
{
OnProductItemSelected(值);
}
}
}
private void OnProductItemSelected(Models.Product selProduct)
{
如果(selProduct为空)返回;
navigationService.NavigateToAsync(selProduct);
}
*****************使用手势识别器更新*****************************
这种行为在iOS和android中完全不正常,它解决了上述问题,但并不精确。有时也会出现故障。有关行为,请参见下面的gif
正如你在下面看到的。有几次点击未被识别。在一个例子中,尽管我试图关闭滑动菜单,但仍会显示详细信息页面
使用的代码是
<CollectionView
SelectionMode="None"
ItemsSource="{Binding Products}"
IsVisible="{Binding Products.Count, Converter={StaticResource CountToBoolConverter}}">
<CollectionView.ItemTemplate>
<DataTemplate>
<!-- <StackLayout> -->
<SwipeView>
<!-- <SwipeView.GestureRecognizers> -->
<!-- <TapGestureRecognizer NumberOfTapsRequired="1" -->
<!-- Command="{Binding BindingContext.ViewProductDetailCommand, Source={x:Reference ProductList}}" -->
<!-- CommandParameter="{Binding .}" /> -->
<!-- </SwipeView.GestureRecognizers> -->
<SwipeView.LeftItems>
<SwipeItems>
<!-- Item History button -->
<SwipeItem
Text="History"
BackgroundColor="{StaticResource ColorSecondary}"
Command="{Binding BindingContext.HistoryBtnCommand, Source={x:Reference ProductList}}"
CommandParameter="{Binding .}"
IsVisible="{Binding ShowProductHistory}" />
</SwipeItems>
</SwipeView.LeftItems>
<SwipeView.RightItems>
<SwipeItems>
<!-- Item History button -->
<SwipeItem
Text="Delete"
BackgroundColor="{StaticResource ColorDanger}"
Command="{Binding BindingContext.DeleteProductCommand, Source={x:Reference ProductList}}"
CommandParameter="{Binding .}"
IsVisible="{Binding ShowItemDeleteButton}" />
<SwipeItem
Text="Add"
BackgroundColor="{StaticResource ColorPrimary}"
Command="{Binding BindingContext.AddProductToProfileCommand, Source={x:Reference ProductList}}"
CommandParameter="{Binding .}"
IsVisible="{Binding ShowAddItemToProfileButton}" />
</SwipeItems>
</SwipeView.RightItems>
<StackLayout>
<StackLayout
Orientation="Horizontal"
Padding="8">
<StackLayout.GestureRecognizers>
<TapGestureRecognizer NumberOfTapsRequired="1"
Command="{Binding BindingContext.ViewProductDetailCommand, Source={x:Reference ProductList}}"
CommandParameter="{Binding .}" />
</StackLayout.GestureRecognizers>
</StackLayout>
</SwipeView>
<!-- </StackLayout> -->
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
从共享代码和屏幕gif来看,
条目
的焦点事件似乎会影响集合视图
的项目点击事件
我建议不要使用CollectionView
的默认项目点击事件,您可以通过使用为项目自定义点击事件
例如,基于您的共享代码,可以修改如下:
...
<StackLayout x:Name="Item"
Orientation="Horizontal"
VerticalOptions="Center"
IsVisible="{Binding ShowAddToCartBtn}">
<StackLayout.GestureRecognizers>
<TapGestureRecognizer NumberOfTapsRequired="1"
Command="{Binding TapCommand}"
CommandParameter="{Binding Source={x:Reference Item}, Path=BindingContext}" />
</StackLayout.GestureRecognizers>
<Entry Placeholder="Quantity"
Keyboard="Numeric"
Text="{Binding EnteredQuantity, Mode=TwoWay}" />
<Label Text="{Binding Units}"
VerticalOptions="Center"
IsVisible="{Binding ShowBaseUnit}" />
<Picker Title="Select an unit"
ItemsSource="{Binding AlternateUnitOptions}"
SelectedItem="{Binding SelectedUnit }"
IsVisible="{Binding ShowAlternateUnit }"
ItemDisplayBinding="{Binding Text}" />
</StackLayout>
...
public ICommand TapCommand
{
get
{
return new Command((e) =>
{
var item = (e as Models.Product);
// logic on item
});
}
}
此外,我发现您还在SwipeView
之外添加了一个StackLayout
。似乎没有必要,您还可以删除包装的StackLayout
,以检查它是否会影响结果。如果是这样,您就不需要尝试我的上述解决方案
========================================更新===================================
在共享链接中,我为StackLayout添加了手势识别器
,并进行了测试,效果良好。我不确定您是否设置了收集视图的SelectionMode=“None”
以下是Xaml的代码:
<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:CollectionViewTest"
x:Class="CollectionViewTest.MainPage"
x:Name="Main"
Title="Products">
<ContentPage.Content>
<CollectionView
SelectionMode="None"
ItemsSource="{Binding Products}">
<CollectionView.ItemTemplate>
<DataTemplate>
<!-- <StackLayout> -->
<SwipeView>
<SwipeView.LeftItems>
<SwipeItems>
<SwipeItem
Text="History"
BackgroundColor="Aqua"
Invoked="SwipeItem_Clicked"/>
</SwipeItems>
</SwipeView.LeftItems>
<SwipeView.RightItems>
<SwipeItems>
<SwipeItem
Text="Delete"
BackgroundColor="Red" />
<SwipeItem
Text="Add to Profile"
BackgroundColor="SpringGreen" />
</SwipeItems>
</SwipeView.RightItems>
<StackLayout x:Name="Item"
Padding="10">
<StackLayout.GestureRecognizers>
<TapGestureRecognizer NumberOfTapsRequired="1"
Command="{Binding TapCommand}"
CommandParameter="{Binding Source={x:Reference Item}, Path=BindingContext}" />
</StackLayout.GestureRecognizers>
<Label
Text="{Binding Brand}" />
<Label
Text="{Binding Description}" />
<Entry
Placeholder="Quantity"
Keyboard="Numeric"
Text="{Binding Quantity}"
HorizontalOptions="Start" />
<Button
Text="Add To Cart"/>
<BoxView
HeightRequest="0.5"
HorizontalOptions="FillAndExpand"
BackgroundColor="Red" />
</StackLayout>
</SwipeView>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</ContentPage.Content>
</ContentPage>
MainViewModel.cs:
public class Product
{
public string Description { get; set; }
public string Brand { get; set; }
public string Quantity { get; set; }
public INavigation navigation { set; get; }
public ICommand TapCommand
{
get
{
return new Command((e) =>
{
var item = (e as Product);
// logic on item
Console.WriteLine("=====" + item.Description);
navigation.PushAsync(new ProductDetailPage());
});
}
}
}
public class MainViewModel : BindableObject
{
private ObservableCollection<Product> products;
public ObservableCollection<Product> Products
{
get => products;
set
{
products = value;
OnPropertyChanged(nameof(products));
}
}
private readonly INavigation navigation;
public MainViewModel(INavigation navigation)
{
this.navigation = navigation;
List<Product> sampleProducts = new List<Product>
{
new Product
{
Brand = "Brand 1",
Description = "Test description",
Quantity = "1",
navigation =this.navigation
},
new Product
{
Brand = "Brand 2",
Description = "Test description 2",
Quantity = "2",
navigation =this.navigation
},
new Product
{
Brand = "Brand 3",
Description = "Test description 3",
Quantity = "3",
navigation =this.navigation
}
};
Products = new ObservableCollection<Product>(sampleProducts);
}
}
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
BindingContext = new MainViewModel(Navigation);
}
private async void SwipeItem_Clicked(object sender, EventArgs e)
{
Console.WriteLine("==SwipeItem_Clicked===");
await DisplayAlert("SwipeItem", "SwipeItem_Clicked", "OK");
}
}
其效果是:
您好,您能解释一下新屏幕如何根据设计的逻辑导航吗?从共享代码中,我找不到调用该页面的位置。@JuniorJiang MSFT我不想让程序在我单击集合视图中的输入字段时导航到新屏幕。对于导航到新页面,我使用wait navigationPage.PushAsync(page);关于所选项目。好的,谢谢更新问题。如果好主意,我会在这里更新。我不会在物理设备iOS中遇到这个问题。需要测试android,如果这只是emulator或更多版本中的问题。这个问题只存在于Android上。在StackLayout中添加手势识别器修复了轻敲问题。但是滑动菜单不起作用。有什么想法吗