如何从基类捕获抽头项(位于模板中)的事件?

时间:2016-11-10 12:00:19

标签: 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.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>

我如何捕捉&#34; OnWidgetTapped&#34;在我的基础xaml类上的事件?

5 个答案:

答案 0 :(得分:4)

我通常在模板中使用自定义可绑定属性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。以下命令示例显示模板如何绑定到命令MyCommand,该命令位于页面的BindingContext中:

Command="{Binding ParentBindingContext.MyCommand, Source={x:Reference Name=MyTemplatePageName}}"

但这预先假定您的网页后面有BindingContext(如ViewModel)。然后,此ViewModel包含&#34; global&#34;整个页面的命令。然后,模板可以访问这些命令(或只是方法),因为他们知道页面的BindingContext

答案 1 :(得分:1)

我将流程描述的答案更改为代码。我的想法是以编程方式创建ItemTemplate,并将具有列表(或网格)的页面传递给其构造函数。定义一个函数ItemTemplateTapped并从模板中调用它。

EventOnGridPage

<?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>

后面的EventOnGridPage代码

public partial class EventOnGridPage : ContentPage
{

    public EventOnGridPage()
    {
        InitializeComponent();

       listView.ItemsSource = new List<Contact>
       {
           new Contact { Name = "Kirti",Status = "True"},
           new Contact { Name = "Nilesh",Status = "False"}
       };

        listView.ItemTemplate = new DataTemplate(loadTemplate);
    }

    private object loadTemplate()
    {
        return new ViewCell() { View = new EventOnGridTemplate(this) };
    }

    public void ItemTemplateTapped(string name)
    {
        DisplayAlert("ItemTemplateTapped", name, "OK");
    }
}

EventOnGridTemplate xaml

<?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>

后面的EventOnGridTemplate代码

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);

    }
}

答案 2 :(得分:0)

您只需要实施OnWidgetTapped方法:

void OnWidgetTapped(object sender, System.EventArgs e)
{
    // Do stuff here
}

答案 3 :(得分:0)

如果您已经在XAML代码中定义了点击手势绑定,则无需添加TapGestureRecognizer,只需将您的方法签名为事件侦听器方法:

您的XAML:

public void OnWidgetTapped(object sender, EventArgs args)
{
// do stuff here
}

关于C#代码:

{{1}}

答案 4 :(得分:0)

另一种解决方案。如果您按照建议实现了OnWidgetTapped,则可以使用sender.Parent.Parent ...直到找到您想要的对象 - 网格或页面。将其转换为例如EventOnGridPage,然后调用该对象的函数。