首页 > 解决方案 > 在 Xamarin Forms 的 Telerik ListView 中,如何处理 Windows 上元素的右键单击事件?

问题描述

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

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

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

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

标签: c#xamarin.formstelerik

解决方案


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

由于您很可能已经在 XamarinForms 中为 RadListView设置了自定义ItemTemplate ,因此您可以考虑创建一个自定义 XamrinForms 控件(例如 Grid、Frame、Border、Label...),它具有 UWP 的自定义渲染器。该呈现器可以订阅UIElement.RightTapped 事件并将通知重新传输到控件的 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>

让我知道这是否适合您。

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


推荐阅读