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}}"