【问题标题】:In a Telerik ListView in Xamarin Forms, how do I handle a right click event for an element on Windows?在 Xamarin Forms 的 Telerik ListView 中,如何处理 Windows 上元素的右键单击事件?
【发布时间】:2020-07-04 11:08:07
【问题描述】:

我的公司有一个跨平台应用程序,主要用于使用 Xamarin 和 Telerik 提供的一些控件的移动设备。最近,我们一直在努力让它在所有平台上都能正常工作(它最初是 Android Java 应用程序的一个端口)。目前的症结在于 Windows:虽然几乎所有东西都运行良好,但 Telerik ListView 却给我们带来了麻烦。

我们目前使用长按事件来显示用于删除项目的 UI。这完美地工作。这是在 Telerik ListView 中使用 GestureRecognizer。问题是我们找不到用鼠标获得类似行为的方法:单击项目具有我们希望保留的效果,并且它已经包含一个不可替代的复选框。理想情况下,我会设置一个右键单击事件并完成它,但 Telerik ListView 控件上没有可用的右键单击事件。由于该控件不是 UIElement,因此我无法以任何我习惯的方式定位其子项,并且节点本身似乎在运行时在实时可视化树中被替换。

我可以看到一个 ExtendedListViewItem 控件,这似乎是我想要提供鼠标事件处理程序的控件,但我不知道如何从顶部引用这些节点。它变得更加棘手,因为这些页面都在 .NET Standard 2.0 类库中,因此任何特定于平台的代码(例如 VisualTreeHelper)只能添加到 UWP 应用程序,然后以某种方式抽象回这个共享 UI 库。

我知道这是一个非常具体的问题,可能很难回答,但搜索我正在尝试做的任何部分似乎可以让我获得大量不相关的指南和信息。

【问题讨论】:

    标签: c# xamarin.forms telerik


    【解决方案1】:

    我评估了在 RadListView 组件的 UWP 部分中创建“RightClicked”事件并将该通知提供给控件的 XamarinForms 部分的方法。从技术上讲,这是可能的,但在编写应该提供通知的 UWP 相关类是内部的。这意味着无法使用 UWP ListViewItems 来提供该通知。

    由于您很可能已经为 XamarinForms 中的 RadListView 设置了自定义 ItemTemplate,因此您可以考虑创建自定义 XamrinForms 控件(例如 Grid、Frame、Border、Label...),它具有UWP 的自定义渲染器。该渲染器可以订阅 UIElement.RightTapped Event 并将通知重新传输到控件的 XamarinForms 部分。

    public class MyRightClickGridRenderer : ViewRenderer<MyRightClickGrid, Grid>
    {
        protected override void OnElementChanged(ElementChangedEventArgs<MyRightClickGrid> e)
        {
            if (this.Element != null)
            {
                if (this.Control == null)
                {
                    var uwpGrid = new Grid { IsRightTapEnabled = true, Background = new SolidColorBrush(Colors.Transparent) };
                    uwpGrid.RightTapped += UwpGrid_RightTapped;
                    this.SetNativeControl(uwpGrid);
                }
            }
            if (this.Element == null)
            {
                if (this.Control != null)
                {
                    ((Grid)this.Control).RightTapped -= UwpGrid_RightTapped;
                }
            }
        }
    
        private void UwpGrid_RightTapped(object sender, Windows.UI.Xaml.Input.RightTappedRoutedEventArgs e)
        {
            ((MyRightClickGrid)this.Element).RaiseRightClicked(sender);
        }
    }
    

    在 XamarinForms 项目中,您可以创建类似的东西

    public class MyRightClickGrid : Grid
    {
        public event EventHandler<TappedEventArgs> RightTapped;
        public void RaiseRightClicked(object sender)
        {
            this.RightTapped?.Invoke(this, new TappedEventArgs(null));
        }
    }
    

    创建此控件后,您可以像这样在 XAML 中使用它:

    <telerikListView:RadListView>
      <telerikListView:RadListView.ItemTemplate>
        <DataTemplate>
          <telerikListViewPrimitives:ListViewTemplateCell>
            <telerikListViewPrimitives:ListViewTemplateCell.View>
              <MyNamespace:MyRightClickGrid >
                ***
              </MyNamespace:MyRightClickGrid >
            </telerikListViewPrimitives:ListViewTemplateCell.View>
          </telerikListViewPrimitives:ListViewTemplateCell>
        </DataTemplate>
      </telerikListView:RadListView.ItemTemplate>
    </telerikListView:RadListView>
    

    让我知道这是否适合你。

    附:这种方法的一个优点是您可以使用相同的渲染器来检索点击的位置。 XamarinForms 仍然不支持此功能,您应该为每个平台创建类似的逻辑以获取该信息。

    【讨论】:

    • 我将此标记为已接受,因为它与我的一位同事最近想出的解决方法有点相似。我们使用不同的消息传递系统将事件订阅到我们需要的位置,并为我们正在显示的 Image 类做了渲染器,但是如果它及时出现,这个答案肯定会让我到达某个地方,并且肯定会帮助其他人我的情况。
    猜你喜欢
    • 2013-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-16
    • 1970-01-01
    • 2017-02-07
    • 1970-01-01
    相关资源
    最近更新 更多