Xamarin RefreshView 导致 UWP 上的点击事件冲突

问题描述 投票:0回答:1

我有一个带有 MainPage(称为 OVerviewPage)的多平台 Xamarin 项目,该项目具有多个 FlexLayouts,每个 FlexLayouts 都绑定到不同的 BindableLayout.ItemSource。每个的 BindableLayout.ItemTemplate 都是一个 ContentView,每个的格式相似,但每个都有不同的 ViewModel.Model。这些 ContentView 中的每一个都有自己的 TapGestureRocgnizer 调用在后面的代码中处理的 Tapped 事件。这些 Flexlayouts 包装在一个 ScrollView 中,而 ScrollView 也包装在一个 RefreshView 中。目的是让用户单击一个 ContentView 以转到详细信息页面。问题是 RefreshView 在为 Windows 桌面上的 UWP 编译时会导致冲突。问题在于,在向下滚动列表并且用户单击 ContentView 之后,将调用另一个 ContentView 的 TappedEvent 处理程序,而不是用户实际单击的处理程序。事实上,当表单第一次加载 3 个 ContentViews 在屏幕上可见时,当其他人滚动到并驻留在前 3 个中的一个所在的位置时,只有前 3 个中的一个的点击事件会响应点击,取决于用户点击屏幕的位置。当我在 xaml 中注释掉 RefreshView 时,点击按预期工作。 我知道 RefreshView 不是为桌面设备设计的,我尝试使用以下方法禁用它:if(Device.Idiom == DeviceIdiom.Desktop){refreshview.IsEnabled = false} 但这不起作用。它在 xaml 中被识别这一事实导致了冲突。 几个注意事项:此页面是 Shell 应用程序的主页,任何解决方案都需要考虑到这一点。我也对解决此问题的大多数解决方案持开放态度。提前致谢

我的概览页面:(只有相关的代码)

            <RefreshView IsRefreshing="{Binding IsRefreshing, Mode=OneWay}"
                     RefreshColor="Teal"
                     Command="{Binding RefreshCommand}">
            
            <ScrollView>
                <StackLayout Margin="10,0,10,0">
                    
                    <FlexLayout Direction="Column"
                                Wrap="NoWrap"
                                AlignItems="Stretch"
                                AlignContent="Center"
                                BindableLayout.ItemsSource="{Binding TrackWarrants}"
                                BindableLayout.ItemTemplate="{StaticResource TrackWarrantTemplate}" 
                                BindableLayout.EmptyViewTemplate="{StaticResource EmptyWarrantTemplate}"/>
                                 
                    <!--Form As-->
                    <FlexLayout Direction="Column"
                            Wrap="NoWrap"
                            AlignItems="Stretch"
                            AlignContent="Center"
                            BindableLayout.ItemsSource="{Binding FormAs}"
                            BindableLayout.ItemTemplate="{StaticResource FormATemplate}" 
                            BindableLayout.EmptyViewTemplate="{StaticResource EmptyFormATemplate}"/>
                    
                    <!--Form Bs-->                      
                    <FlexLayout Direction="Column"
                                Wrap="NoWrap"
                                AlignItems="Stretch"
                                AlignContent="Center"
                                BindableLayout.ItemsSource="{Binding FormBs}"
                                BindableLayout.ItemTemplate="{StaticResource FormBTemplate}" 
                                BindableLayout.EmptyViewTemplate="{StaticResource EmptyFormBTemplate}"/>

                    <!--Form Cs-->
                    <FlexLayout Direction="Column"
                                Wrap="NoWrap"
                                AlignItems="Stretch"
                                AlignContent="Center"
                                BindableLayout.ItemsSource="{Binding FormCs}"
                                BindableLayout.ItemTemplate="{StaticResource FormCTemplate}" 
                                BindableLayout.EmptyViewTemplate="{StaticResource EmptyFormCTemplate}"/>

ContentViews 代码:(例如,只有 1 个,除了数据放置之外它们都是相同的)

    <ContentView.Content>
    <Frame>
        <Frame.GestureRecognizers>
        <TapGestureRecognizer CommandParameter="{Binding}" Tapped="FormA_Tapped" />
        </Frame.GestureRecognizers>

        <Grid  >
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="30"/>
                <ColumnDefinition Width="70"/>
                <ColumnDefinition Width="25"/>
                <ColumnDefinition Width="25"/>
                <ColumnDefinition Width="25"/>
                <ColumnDefinition Width="30"/>
                <ColumnDefinition Width="95"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="25"/>
                <RowDefinition Height="25"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="20"/>
            </Grid.RowDefinitions>

            <StackLayout Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" Grid.ColumnSpan="2" HorizontalOptions="StartAndExpand" VerticalOptions="Start" 
                         Orientation="Horizontal" WidthRequest="130" >
                <Label FontFamily="Material" FontSize="Large" Text="{Binding Icon}" HorizontalOptions="Start" VerticalOptions="Start"
                   Grid.Column="0" Grid.Row="0" Grid.RowSpan="2">
                    <Label.Triggers>
                        <DataTrigger TargetType="Label" Binding="{Binding Source={x:Reference Reject},Path=Text}" Value="True">
                            <Setter Property="TextColor" Value="Black"/>
                        </DataTrigger>
                    </Label.Triggers>
                </Label>
                <Label  FontSize="Medium" FontAttributes="Bold" HorizontalOptions="Start"
                    VerticalOptions="Start" x:Name="FormID">
                    <Label.FormattedText>
                        <FormattedString>
                            <Span Text="{Binding FormNumber}"/>
                            <Span Text="-"/>
                            <Span Text="{Binding LineNo}"/>
                        </FormattedString>
                    </Label.FormattedText>
                    <Label.Triggers>
                        <DataTrigger TargetType="Label" Binding="{Binding Source={x:Reference Reject},Path=Text}" Value="True">
                            <Setter Property="TextColor" Value="Black"/>
                        </DataTrigger>
                    </Label.Triggers>
                </Label>
                <StackLayout.Triggers>
                    <DataTrigger TargetType="StackLayout" Binding="{Binding Source={x:Reference Reject},Path=Text}" Value="True">
                        <Setter Property="BackgroundColor" Value="Salmon"/>
                    </DataTrigger>
                </StackLayout.Triggers>
            </StackLayout>
            
            <Label Text="{Binding Territory}" 
               FontSize="Small"
               VerticalOptions="Center"
               HorizontalOptions="Start"
               Grid.Column="0"
               Grid.Row="3" Grid.ColumnSpan="6" />

            <Label FontFamily="Material" 
               FontSize="Small" 
               Text="{x:Static md:MaterialDesignIcons.MyLocation}" 
               HorizontalOptions="Center"
               Grid.Column="2"
               Grid.Row="0"  />

            <Label Text="{Binding From}" 
               FontSize="Small"     
               Grid.Column="3"
               Grid.Row="0" Grid.ColumnSpan="4" />

            <Label FontFamily="Material" 
               FontSize="Small" 
               Text="{x:Static md:MaterialDesignIcons.LocationOn}" 
               HorizontalOptions="Center"
               Grid.Column="2"
               Grid.Row="1" />

            <Label Text="{Binding End}" 
               FontSize="Small"   
               Grid.Column="3"    
               Grid.Row="1"  Grid.ColumnSpan="4"  />
            
            <Label FontSize="Small"  
               FontAttributes="Bold" 
               HorizontalOptions="StartAndExpand"
               Grid.Column="1"
               Grid.Row="2"   
               Grid.ColumnSpan="5">
                <Label.FormattedText>
                    <FormattedString>
                        <Span Text="Speed: "/>
                        <Span Text="{Binding Speed}"/>
                    </FormattedString>
                </Label.FormattedText>
            </Label>

            <Label x:Name="Reject" Text="{Binding Rejected}" 
               FontSize="Small"                  
               Grid.Column="0"
               Grid.Row="3" IsVisible="False" />
            <Label x:Name="status" Text="{Binding StatusID}" 
               FontSize="Small"                  
               Grid.Column="0"
               Grid.Row="3" IsVisible="False" ></Label>
        </Grid>
    </Frame>
</ContentView.Content>

ContentView背后的相关代码:

        public FormACard()
    {
        InitializeComponent();
        formaviewmodel = new FormAViewModel();
        BindingContext = formaviewmodel;
    }
    private async void FormA_Tapped(object sender, EventArgs e)
    {
        var user = App.LoggedInUser.UserName;

        var ea = e as TappedEventArgs;
        if (ea.Parameter != null)
        {
            var forminfo = JsonConvert.SerializeObject(ea.Parameter);
            string _forminfo = Uri.EscapeDataString(forminfo);
            FormA forma = (FormA)ea.Parameter;
            bool rejectAck = forma.RejectionAcked;
            bool rejected = forma.Rejected;
            string requestor = forma.RequestedBy;
            if (!rejectAck && rejected && requestor == user)
            {
                await Shell.Current.GoToAsync($"{nameof(RejectACK)}?{nameof(RejectACK.Contentx)}={_forminfo}");
            }
            else
            {
                await Shell.Current.GoToAsync($"viewforma?Content={_forminfo}");
            }

        }
    }

仅供参考 - 如果这看起来很熟悉,我在信息较少时将此问题发布在另一个线程中。我关闭了另一个并用新信息打开了这个。

xaml xamarin.forms pull-to-refresh
1个回答
0
投票

问题是,在向下滚动列表并且用户单击 ContentView 之后,将调用另一个 ContentView 的 TappedEvent 处理程序,而不是用户实际单击的处理程序。

关于“Xamarin RefreshView 导致 UWP 上的 Tapped Event 冲突”,我在 GitHub 上发现了这个:[Bug] 使用由 RefreshView 包装的 BindableLayout 的错误行为。链接提到:

根据您的复制品对此进行了测试。发现它与 BindableLayout 无关:您可以完全消除它,只需直接创建 20 帧,它会导致同样的错误行为。似乎 - 只要使用 RefreshView (UWP RefreshContainer) - 点击事件就会被分派到错误的 UI 控件和/或滚动偏移没有被正确考虑。 目前不确定这是 XF 错误还是 UWP RefreshContainer 中的问题,即使我没有找到匹配的问题(经过短暂搜索)。

如果

RefreshView
不影响你整个程序的运行,可以去掉。否则你可以等待错误被修复。

希望对你有帮助

© www.soinside.com 2019 - 2024. All rights reserved.