Reputation: 11211
Goal:
I want to run some method from ContentPage (class that manages XAML) inside ExtendableButtonList (custom View).
Problem:
ActionHandler
- which represents event to call in ExtendableButtonList - always equals null. Every other property, configured the same way works, instead of this.
Is it even possible to pass a method using binding?
I'm sure that I'm not passing null value to my object.
XAML:
<ListView x:Name="emView">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="20">
<StackLayout BackgroundColor="Silver" Padding="20">
[...]
<customControls:ExtendableButtonList ActionHandler="{Binding ActionHandler}"></customControls:ExtendableButtonList>
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
ExtendableButtonList:
public class ExtendableButtonList : StackLayout
{
public static readonly BindableProperty ActionHandlerProperty = BindableProperty.Create(
propertyName: "ActionHandler",
returnType: typeof(OneOfButtonClickedHandler),
declaringType: typeof(ExtendableButtonList),
defaultValue: default(OneOfButtonClickedHandler));
public OneOfButtonClickedHandler ActionHandler
{
get { return (OneOfButtonClickedHandler)GetValue(ActionHandlerProperty); }
set { SetValue(ActionHandlerProperty, value); }
}
public delegate void OneOfButtonClickedHandler(int buttonId, int action);
public event OneOfButtonClickedHandler OneOfButtonsClicked;
public ExtendableButtonList()
{
[...]
PropertyChanged += CheckIfPropertyLoaded;
}
void CheckIfPropertyLoaded(object sender, PropertyChangedEventArgs e)
{
//wait until property ActionHandler will be loaded
if(e.PropertyName == "ActionHandler")
{
OneOfButtonsClicked += ActionHandler;
}
}
[...]
void CalculationsFinished(){
[...]
OneOfButtonsClicked(buttonId, action);
}
}
Upvotes: 1
Views: 1582
Reputation: 546
Here is how they (XF) do,
public static readonly BindableProperty CommandProperty = BindableProperty.Create("Command", typeof(ICommand), typeof(Button), null, propertyChanged: (bo, o, n) => ((Button)bo).OnCommandChanged());
public static readonly BindableProperty CommandParameterProperty = BindableProperty.Create("CommandParameter", typeof(object), typeof(Button), null,
propertyChanged: (bindable, oldvalue, newvalue) => ((Button)bindable).CommandCanExecuteChanged(bindable, EventArgs.Empty));
public ICommand Command
{
get { return (ICommand)GetValue(CommandProperty); }
set { SetValue(CommandProperty, value); }
}
public object CommandParameter
{
get { return GetValue(CommandParameterProperty); }
set { SetValue(CommandParameterProperty, value); }
}
public event EventHandler Clicked;
void IButtonController.SendClicked()
{
ICommand cmd = Command;
if (cmd != null)
cmd.Execute(CommandParameter);
EventHandler handler = Clicked;
if (handler != null)
handler(this, EventArgs.Empty);
}
And in your viewmodel or whatever, create an ICommand property and bind it to Command.
Upvotes: 2