1
votes

I'm in Xamarin and I am trying to coax an event into a command using the EventToCommandBehavior trick. The sample code I am following is also described here. problem I'm having is that the BehaviorBase's OnAttachedTo override isn't firing and this means that the event wire-up isn't happening.

How do I make these commands fire?

A secondary issue is that the whole view doesn't load while this issue is present. If I comment out the XAML, the view works. Maybe this is a clue? Why wouldn't the whole view load because of this? I would think that only the behavior wouldn't work, not the entire view.

My question is similar to this one, but the issue is different.

Now for the details:

I've copied over, from the sample the two classes BehaviorBase and EventToCommandBehavior. The code comes from here.

My View

<?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="MyApp.Views.MyPage" xmlns:v="clr-namespace:MyApp.Views;assembly=MyApp" xmlns:b="clr-namespace:MyApp.Behaviors;assembly=MyApp" xmlns:c="clr-namespace:MyApp.Converters;assembly=MyApp">
    <ContentPage.Behaviors>
        <b:EventToCommandBehavior EventName="Disappearing" Command="{Binding DisappearingCommand}" />
        <b:EventToCommandBehavior EventName="Appearing" Command="{Binding AppearingCommand}" />
    </ContentPage.Behaviors>-->
    <ContentPage.Content>
        <StackLayout>
            <Entry Text="{Binding Name}"></Entry>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

In my ViewModel, I have the command AppearingCommand and DisappearingCommand. The View's code-behind has just the constructor.

When I launch this page, OnEventNameChange fires in EventToCommandBehavior, but behavior.AssociatedObject is null, so it quits. That variable is null because OnAttachedTo never fires. Why not? What am I doing wrong?

This Fires:

private static void OnEventNameChanged(BindableObject bindable, object oldValue, object newValue)
{
    var behavior = (EventToCommandBehavior)bindable;
    if (behavior.AssociatedObject == null)
    {
        return;
    }

    string oldEventName = (string)oldValue;
    string newEventName = (string)newValue;

    behavior.DeregisterEvent(oldEventName);
    behavior.RegisterEvent(newEventName);
}

But this never does:

protected override void OnAttachedTo(View bindable)
{
    base.OnAttachedTo(bindable);
    RegisterEvent(EventName);
}

The base.OnAttachedTo is what sets behavior.AssociatedObject to something. Here's a copy of it:

protected override void OnAttachedTo(T bindable)
{
    base.OnAttachedTo(bindable);
    AssociatedObject = bindable;

    if (bindable.BindingContext != null)
    {
        BindingContext = bindable.BindingContext;
    }

    bindable.BindingContextChanged += OnBindingContextChanged;
}
1
Where are you setting an instance of your ViewModel to the page's BindingContext?Damian
It's elsewhere and it's the usual code var v = new MyView(); v.BindingContext = new MyViewModel();010110110101

1 Answers

0
votes

I have faced the same problem. The solution is to change the base class of the EventToCommandBehavior class from BehaviorBase<View> to BehaviorBase<VisualElement>. So it should be the following:

public class EventToCommandBehavior : BehaviorBase<VisualElement>
{
    ...
}