Xaml 如何从基类中捕获点击项(位于模板中)的事件?
我有一个基本网格Xaml 如何从基类中捕获点击项(位于模板中)的事件?,xaml,events,xamarin,binding,event-handling,Xaml,Events,Xamarin,Binding,Event Handling,我有一个基本网格 <Grid Grid.Row="1" Grid.Column="1" x:Name="GridName"> <StackLayout Orientation="Vertical"> <art:GridOptionsView ItemsSource="{Binding Items}" > <art:GridOptionsView.ItemTem
<Grid Grid.Row="1" Grid.Column="1" x:Name="GridName">
<StackLayout Orientation="Vertical">
<art:GridOptionsView ItemsSource="{Binding Items}" >
<art:GridOptionsView.ItemTemplate>
<DataTemplate>
<uikit:DashboardItemTemplate />
</DataTemplate>
</art:GridOptionsView.ItemTemplate>
</art:GridOptionsView>
</StackLayout>
</Grid>
它使用以下DashboardItemTemplate
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
BackgroundColor="White">
<ContentView.Content>
<Grid Padding="0">
<StackLayout VerticalOptions="Center" HorizontalOptions="Center" Orientation="Vertical" Spacing="10">
<Grid>
<Label Text="" Style="{StaticResource FontIcon}" HorizontalTextAlignment="Center" Opacity="1" FontSize="130" TextColor="{Binding BackgroundColor}" VerticalOptions="Center" HorizontalOptions="Center" IsVisible="{Binding Source={x:Reference Root}, Path=ShowiconColoredCircleBackground}" />
<Label Text="{Binding Icon}" Style="{StaticResource FontIcon}" Opacity="1" TextColor="White" VerticalOptions="Center" HorizontalOptions="Center" />
</Grid>
<Label Text="{Binding Name}" TextColor="{Binding Source={x:Reference Root}, Path=TextColor}" FontSize="14" HorizontalTextAlignment="Center">
</Label>
</StackLayout>
</Grid>
</ContentView.Content>
<ContentView.GestureRecognizers>
<TapGestureRecognizer Tapped="OnWidgetTapped" />
</ContentView.GestureRecognizers>
</ContentView>
如何在我的基本xaml类上捕获“OnWidgetTapped”事件?您只需要实现您的
OnWidgetTapped
方法:
void OnWidgetTapped(object sender, System.EventArgs e)
{
// Do stuff here
}
如果您已经在XAML代码中定义了点击手势绑定,则无需添加点击手势识别器,只需将您的方法签名到事件侦听器方法: 您的XAML:
<ContentView.GestureRecognizers>
<TapGestureRecognizer Tapped="OnWidgetTapped" />
</ContentView.GestureRecognizers>
我将答案从流程描述更改为代码。其思想是以编程方式创建ItemTemplate,并将带有列表(或网格)的页面传递给其构造函数。定义函数ItemTemplateTapped并从模板调用它 事件翻页
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ButtonRendererDemo.EventOnGridPage">
<ListView x:Name="listView" >
</ListView>
</ContentPage>
另一个解决方案。如果按照建议实现OnWidgetTapped,则可以使用sender.Parent.Parent。。。直到你找到你想要的对象-网格或页面。将其强制转换为例如EventOnGridPage,然后调用该对象的函数。我通常使用模板中的自定义可绑定属性
ParentBindingContext
来执行此操作:
public class MyTemplate : ContentPage
{
public static BindableProperty ParentBindingContextProperty = BindableProperty.Create(nameof(ParentBindingContext),
typeof(object), typeof(BasePageTemplate));
public object ParentBindingContext
{
get { return GetValue(ParentBindingContextProperty); }
set { SetValue(ParentBindingContextProperty, value); }
}
}
然后在页面(包含模板)中设置ParentBindingContext
:
<DataTemplate>
<template:MyTemplate ParentBindingContext="{Binding BindingContext, Source={x:Reference Name=MyPageName}}" />
</DataTemplate>
但这前提是您的页面后面有一个
BindingContext
(类似于ViewModel)。然后,此ViewModel包含整个页面的“全局”命令。这些命令(或者仅仅是方法)可以被模板访问,因为它们知道页面的BindingContext
。我实际上想在基本网格中引发OnWidgetTapped事件,而不是在模板本身中。我怎样才能做到这一点?类似event+=newevent的内容,我实际上希望在基本网格中而不是在模板本身中引发OnWidgetTapped事件。我怎样才能做到这一点?类似事件+=新事件,进入GridView你使用Grial组件吗?我必须承认我完全被打动了,我希望我能遵循这背后的整个流程。我将使用grid编写一些代码,但不能准确地重现Grial。这对你来说可以接受吗?当然不会有问题抱歉:-)常规网格没有项目源代码,也不可模板化,所以我的代码将基于ListView,但想法是一样的,如果所有这些都太复杂,只需使用Messenger:-)在页面中订阅并从模板中激发。尽管有些人不喜欢使用messenger,并试图不惜一切代价避免使用它,但请告诉我BasePageTemplate是什么?我通过DataTemplateSelector根据某些条件分配模板。根据当前模型的不同,我有不同的模板要显示。在哪里可以设置ParentBindingContext?BasePageTemplate
是模板类的名称。对于上面的示例,它将是DashboardItemTemplate
<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ButtonRendererDemo.EventOnGridTemplate"
BackgroundColor="Green">
<Label Text="{Binding Name}" x:Name="myLabel"></Label>
</ContentView>
public partial class EventOnGridTemplate
{
EventOnGridPage parent;
public EventOnGridTemplate(EventOnGridPage parent)
{
this.parent = parent;
InitializeComponent();
var tapGestureRecognizer = new TapGestureRecognizer();
tapGestureRecognizer.Tapped += TapGestureRecognizer_Tapped;
myLabel.GestureRecognizers.Add(tapGestureRecognizer);
}
private void TapGestureRecognizer_Tapped(object sender, EventArgs e)
{
parent.ItemTemplateTapped(myLabel.Text);
}
}
public class MyTemplate : ContentPage
{
public static BindableProperty ParentBindingContextProperty = BindableProperty.Create(nameof(ParentBindingContext),
typeof(object), typeof(BasePageTemplate));
public object ParentBindingContext
{
get { return GetValue(ParentBindingContextProperty); }
set { SetValue(ParentBindingContextProperty, value); }
}
}
<DataTemplate>
<template:MyTemplate ParentBindingContext="{Binding BindingContext, Source={x:Reference Name=MyPageName}}" />
</DataTemplate>
Command="{Binding ParentBindingContext.MyCommand, Source={x:Reference Name=MyTemplatePageName}}"