C# 在Xamarin表单中的Telerik ListView中,如何处理Windows上某个元素的右键单击事件?

C# 在Xamarin表单中的Telerik ListView中,如何处理Windows上某个元素的右键单击事件?,c#,xamarin.forms,telerik,C#,Xamarin.forms,Telerik,我的公司有一个跨平台应用程序,主要用于使用Xamarin和Telerik的一些控件的移动设备。最近,我们已经投入了更多的工作,以使其在所有平台上正常工作(它最初是Android Java应用程序的一个端口)。目前的症结在于Windows:虽然几乎所有的东西都工作得相当好,但Telerik ListView给我们带来了麻烦 我们目前使用长按事件来显示删除项目的UI。这很好用。这是在Telerik ListView中使用手势识别器。问题是,我们无法找到一种方法来获得类似的鼠标行为:单击该项目具有我们

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

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

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


我知道这是一个非常具体的问题,可能很难回答,但是搜索我要做的任何部分似乎都会得到大量不相关的指南和信息。

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

既然您已经在XamarinForms的RADISListVIEW中设置了一个自定义的“强> ITEMDSATE/SUBLY”,您可以考虑创建一个自定义的XAMRIOFFASE控件(例如网格、框架、边框、标签……),它具有UWP的自定义渲染器。该呈现程序可以订阅,并将通知重新传输到控件的一部分

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);
    }
}
公共类MyRightClickGridRenderer:ViewRenderer
{
受保护的覆盖无效OnElementChanged(ElementChangedEventArgs e)
{
if(this.Element!=null)
{
if(this.Control==null)
{
var uwpGrid=new Grid{IsRightTapEnabled=true,Background=new SolidColorBrush(Colors.Transparent)};
uwpGrid.rightstapped+=uwpGrid_rightstapped;
本发明公开了一种新的方法:设置国家控制(uwpGrid);
}
}
if(this.Element==null)
{
if(this.Control!=null)
{
((网格)this.Control).rightstapped-=UwpGrid_rightstapped;
}
}
}
私有void UwpGrid_rightstapped(对象发送方,Windows.UI.Xaml.Input.rightstappedroutedventargs e)
{
((MyRightClickGrid)this.Element).RaiserRightClicked(发件人);
}
}
在XamarinForms项目中,您可以创建类似的内容

public class MyRightClickGrid : Grid
{
    public event EventHandler<TappedEventArgs> RightTapped;
    public void RaiseRightClicked(object sender)
    {
        this.RightTapped?.Invoke(this, new TappedEventArgs(null));
    }
}
public类MyRightClickGrid:Grid
{
公共事件处理程序;
public void RaiseRightClicked(对象发送者)
{
this.rightstapped?.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仍然不支持此功能,您应该为每个平台创建类似的逻辑以获取该信息。

我将此标记为已接受,因为它与我的一位同事最近提出的解决方案大致相似。我们使用了一个不同的消息传递系统来获取事件订阅到我们需要的位置,并为我们正在显示的图像类执行渲染器,但是如果这个答案及时出现在这里,它肯定会帮助到我所在的其他人。