Xamarin.forms Xamarin forms Swipe视图在集合视图中,即使在条目字段中单击,也会激发选定项

Xamarin.forms Xamarin forms Swipe视图在集合视图中,即使在条目字段中单击,也会激发选定项,xamarin.forms,Xamarin.forms,我在数据模板中有一个带有滑动视图的集合视图。在数据模板中,我有一个条目和一个选择器。每当我在输入字段中单击时,键盘就会出现,并选择EdItem事件激发。对于单元格,这是第一次发生。之后,这种行为就消失了。有关行为,请参见下面的gif 我的XAML是这样的 <CollectionView SelectionMode="Single" ItemsSource="{Binding Pro

我在数据模板中有一个带有滑动视图的集合视图。在数据模板中,我有一个条目和一个选择器。每当我在输入字段中单击时,键盘就会出现,并选择EdItem事件激发。对于单元格,这是第一次发生。之后,这种行为就消失了。有关行为,请参见下面的gif

我的XAML是这样的

<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中添加手势识别器修复了轻敲问题。但是滑动菜单不起作用。有什么想法吗