我的公司有一个跨平台应用程序,主要用于使用Xamarin的移动设备,并由Telerik进行一些控制。最近,我们投入了更多的工作来使它在所有平台上正常工作(它最初是安卓Java应用程序的一个端口(。目前的症结在于Windows:虽然几乎所有东西都运行得很好,但Telerik ListView给我们带来了麻烦。
我们目前使用长按事件来显示删除项目的UI。这非常有效。这是在Telerik ListView中使用手势识别器。问题是,我们找不到用鼠标获得类似行为的方法:点击项目具有我们希望保留的效果,并且它已经包含了一个不可替代的复选框。理想情况下,我会设置一个右击事件并完成它,但Telerik ListView控件上没有可用的右击事件。由于控件不是UIElement,我无法以我习惯的任何方式定位其子控件,并且节点本身似乎在运行时被替换为实时可视化树中的节点。
我可以看到一个ExtendedListViewItem控件,它似乎是我想给鼠标事件处理程序的控件,但我不知道如何从顶部引用这些节点。这变得更加棘手,因为这些页面都在.NET Standard 2.0类库中,所以任何特定于平台的代码(比如VisualTreeHelper(都只能添加到UWP应用程序中,然后以某种方式抽象回这个共享UI库。
我知道这是一个非常具体的问题,可能很难回答,但搜索我试图做的任何部分似乎都会给我带来大量无关的指南和信息。
我评估了在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>
让我知道这是否适合你。
附言:这种方法的一个优点是,您可以使用相同的渲染器来检索单击产生的位置。XamarinForms仍然不支持此功能,您应该为每个平台创建类似的逻辑来获取这些信息。