将方法作为参数传递给XAML对象

时间:2016-10-16 11:34:59

标签: c# xaml xamarin xamarin.forms

我目前正在使用CustomObject,每个平台都需要CustomObjectRenderer

我想从XAML端将一个方法作为参数传递给这个对象,所以我可以从我的渲染器中使用这个回调。

<control:CustomObject Callback="CallbackFunction"/>

然后在PCL部件的 MainPage.xaml.cs 中声明CallbackFunction(object param)

public partial class MainPage : ContentPage
{
    public MainPage()
    {
        base.BindingContext = this;
    }

    public void CallbackFunction(object param)
    {
        Debug.WriteLine((object as Element).Name);
    }
}

所以,如果我理解得很好,我的CustomObject必须是这样的:

public CustomObject : Object
{
    public Action<object> Callback { get; set; }
}

但我有一个关于XAML解析的错误..我不明白为什么会抛出这个错误..

最后,我想要做什么,从渲染器调用此方法,然后处理事物,从PCL部分从MainPage.xaml.cs执行操作。

public class CustomObjectRenderer : ObjectRenderer
{
    NativeObject nativeObject;
    CustomObject customObject;

    protected override void OnElementChanged(ElementChangedEventArgs<CustomObject> e)
    {
        base.OnElementChanged(e);

        if (e.NewElement != null)
        {
            customObject = e.NewElement as CustomObject;
            nativeObject = Control as NativeObject;
        }
    }

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);
    }

    // Etc etc .... 

    private void METHOD_CALLED_BY_EVENT(object o)
    {
        // This method get call by the renderer event and then, I want to call 
        // the method CallbackFunction(object); and do actions.
        customObject.Callback(o as OBJECT_PARAM);
    }
}

好的,我向你解释我的问题有点困难,所以如果你不了解某些事情,请告诉我。

2 个答案:

答案 0 :(得分:1)

您可以通过使用事件来实现此目的。

<强> MyView的

public class MyView : View
{
    public event EventHandler<string> MyEvent;

    public void RaiseEvent(string parameter)
    {
        MyEvent?.Invoke(this, parameter);
    }
}

<强> Page.xaml

<local:MyView MyEvent="MyView_OnMyEvent"></local:MyView>

<强> Page.xaml.cs

public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();
    }

    private void MyView_OnMyEvent(object sender, string e)
    {
        Debug.WriteLine(e);
    }
}

<强>渲染

public class MyViewRenderer : ViewRenderer<MyView, SomeNativeView>
{
    private void METHOD_CALLED_BY_EVENT(string param)
    {
        Element.RaiseEvent(param);
    }
}

答案 1 :(得分:0)

经过多次尝试,但是没有用,我有了一个想法,我尝试了,并且通过询问我的问题,它按照我想要的方式工作。

首先,创建自定义对象!

<强> CustomView

public class CustomView : View
{
    public static readonly BindableProperty MainPageCallbackProperty =
        BindableProperty.Create(nameof(MainPageCallback), typeof(Action<object>), typeof(CustomMap), null);
    public Action<object> MainPageCallback
    {
        get { return (Action<object>)GetValue(MainPageCallbackProperty); }
        set { SetValue(MainPageCallbackProperty, value); }
    }
}

我们使用Action这是方法/回调的容器。但在我的示例中,我们将使用Action<object>。为什么?因为它允许我们让一个对象对我们的回调有参数,所以我们将能够从渲染器中恢复数据。

然后,通过示例创建一个名为 MainPage.xaml 的页面。在此新页面的XAML部分中,添加以下代码:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:control="clr-namespace:Project.CustomControl;assembly=Project"
             x:Class="Project.Page.MainPage">

  <ContentPage.Content>
    <control:CustomView MainPageCallback="{Binding MainPageCallbackAction}"
                        VerticalOptions="Fill" HorizontalOptions="Fill"/>
  </ContentPage.Content>

</ContentPage>

关于这个XAML,我们有两个部分感兴趣。

  • XAML'参考'

    xmlns:control="clr-namespace:Project.CustomControl;assembly=Project"

通过这些xmlns,您可以访问自定义控件。

  • 页面内容

    <ContentPage.Content> <control:CustomView MainPageCallback="{Binding MainPageCallbackAction}" VerticalOptions="Fill" HorizontalOptions="Fill"/> </ContentPage.Content>

现在,我们将对象的MainPageCallback绑定到 C#方面声明的MainPageCallbackAction

之后,我们的 MainPage.xaml.cs 似乎是这样的:

public partial class MainPage : ContentPage
{
    public Action<object> MainPageCallbackAction { get; set; }

    public MainPage()
    {
        base.BindingContext = this;
        MainPageCallbackAction = MainPageCallbackMethod;
        InitializeComponent();
    }

    private void MainPageCallbackMethod(object param)
    {
        Device.BeginInvokeOnMainThread(() =>
        {
            Debug.WriteLine("Welcome to the Callback :)");
            Debug.WriteLine("Emixam23 - Example");
        });
    }
}

现在,最后要看的是CustomViewRenderer

public class CustomViewRenderer : ViewRenderer<CustomView, NativeView>
{
    CustomView customView;
    NativeView nativeView;

    protected override void OnElementChanged(ElementChangedEventArgs<CustomView> e)
    {
        base.OnElementChanged(e);

        if (e.NewElement != null)
        {
            customView = e.NewElement as CustomView;
            nativeView = Control as NativeView;
            NativeView.CLicked += METHOD_CALLED_BY_EVENT;
        }
    }

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);
    }

    private void METHOD_CALLED_BY_EVENT(object sender, EventArgs ea)
    {
        customView.MainPageCallback(ea.something.information);
    }
}

然后,看看输出,您将能够看到以下内容:

  • 欢迎使用回调:)
  • Emixam23 - 示例

我希望这个答案很明确并帮助你!