#c# #xaml #xamarin #xamarin.forms
#c# #xaml #xamarin #xamarin.forms
Вопрос:
В настоящее время я работаю с a CustomObject
, который нуждается в a CustomObjectRenderer
для каждой платформы.
Я хотел бы передать метод в качестве параметра этому объекту со стороны XAML, чтобы я мог использовать этот обратный вызов из моего средства визуализации.
<control:CustomObject Callback="CallbackFunction"/>
Затем CallbackFunction(object param)
он объявляется в MainPage.xaml.cs части PCL.
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.. Я не понимаю, почему возникает эта ошибка..
В конце, что я хочу сделать, это вызвать этот метод из средства визуализации, а затем обрабатывать вещи, выполнять действия из MainPage.xaml.cs, из части PCL.
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);
}
}
Хорошо, мне немного сложно объяснить вам свою проблему, поэтому, если вы чего-то не понимаете, дайте мне знать.
Комментарии:
1. Блестящая идея. Я мог бы увидеть несколько очень полезных приложений для этого метода. Но знайте, что XAML создает экземпляры объектов и использует преобразователи строк в объекты. Для этой цели вам может понадобиться пользовательский конвертер.
2. Взгляните на мой ответ 😉
Ответ №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. Спасибо, такой хороший ответ! Однако я бы предпочел обратный вызов :/ Но ваше решение мне подходит 🙂
Ответ №2:
После многих попыток, которые не сработали, у меня появилась идея, я попробовал, и она работает так, как я хотел, задав свой вопрос.
Сначала создайте свой пользовательский объект!
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
which является контейнером для метода / обратного вызова. Но в моем примере мы будем использовать 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 ‘References’
xmlns:control="clr-namespace:Project.CustomControl;assembly=Project"
С помощью этого xmlns
вы можете получить доступ к своему пользовательскому элементу управления.
- Содержимое страницы
<ContentPage.Content>
<control:CustomView MainPageCallback="{Binding MainPageCallbackAction}"
VerticalOptions="Fill" HorizontalOptions="Fill"/>
</ContentPage.Content>
Теперь мы привязываем MainPageCallback
наш объект к объекту MainPageCallbackAction
, объявленному на стороне C #.
После этого наш 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 — Пример
Я надеюсь, что этот ответ понятен и поможет вам!