Event is not fired using EventToCommand at Xamarin forms

I have already attached a project trying to use EventToCommand and fire an event, but seems that is not working.
Can you please help with that?

Answers

  • siaelenisiaeleni Member ✭✭
    edited September 2018

    I couldn't attach the whole project, so I will give you the source code here:

        using System;
        using System.Collections.Generic;
        using System.Text;
        using Xamarin.Forms;
    
        namespace Behaviors
        {
            public class BehaviorBase<T> : Behavior<T> where T : BindableObject
            {
                public T AssociatedObject { get; private set; }
    
                protected override void OnAttachedTo(T bindable)
                {
                    base.OnAttachedTo(bindable);
                    AssociatedObject = bindable;
    
                    if (bindable.BindingContext != null)
                    {
                        BindingContext = bindable.BindingContext;
                    }
                    bindable.BindingContextChanged += OnBindingContextChanged;
                }
    
                protected override void OnDetachingFrom(T bindable)
                {
                    base.OnDetachingFrom(bindable);
                    bindable.BindingContextChanged -= OnBindingContextChanged;
                    AssociatedObject = null;
                }
    
                void OnBindingContextChanged(object sender, EventArgs e)
                {
                    OnBindingContextChanged();
                }
    
                protected override void OnBindingContextChanged()
                {
                    base.OnBindingContextChanged();
                    BindingContext = AssociatedObject.BindingContext;
                }
    
            }
        }
    
    
    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Reflection;
    using System.Text;
    using System.Windows.Input;
    
    using Xamarin.Forms;
    
    namespace Behaviors
    {
        public class EventToCommandBehavior : BehaviorBase<View>
        {
            Delegate eventHandler;
    
            public static readonly BindableProperty EventNameProperty = BindableProperty.Create("EventName", typeof(string), typeof(EventToCommandBehavior), null, propertyChanged: OnEventNameChanged);
            public static readonly BindableProperty CommandProperty = BindableProperty.Create("Command", typeof(ICommand), typeof(EventToCommandBehavior), null);
            public static readonly BindableProperty CommandParameterProperty = BindableProperty.Create("CommandParameter", typeof(object), typeof(EventToCommandBehavior), null);
            public static readonly BindableProperty InputConverterProperty = BindableProperty.Create("Converter", typeof(IValueConverter), typeof(EventToCommandBehavior), null);
    
            public string EventName
            {
                get { return (string)GetValue(EventNameProperty); }
                set { SetValue(EventNameProperty, value); }
            }
    
            public ICommand Command
            {
                get { return (ICommand)GetValue(CommandProperty); }
                set { SetValue(CommandProperty, value); }
            }
    
            public object CommandParameter
            {
                get { return GetValue(CommandParameterProperty); }
                set { SetValue(CommandParameterProperty, value); }
            }
    
            public IValueConverter Converter
            {
                get { return (IValueConverter)GetValue(InputConverterProperty); }
                set { SetValue(InputConverterProperty, value); }
            }
    
            protected override void OnAttachedTo(View bindable)
            {
                base.OnAttachedTo(bindable);
                RegisterEvent(EventName);
            }
    
            protected override void OnDetachingFrom(View bindable)
            {
                DeregisterEvent(EventName);
                base.OnDetachingFrom(bindable);
            }
    
            void RegisterEvent(string name)
            {
                if (string.IsNullOrWhiteSpace(name))
                {
                    return;
                }
    
                EventInfo eventInfo = AssociatedObject.GetType().GetRuntimeEvent(name);
                if (eventInfo == null)
                {
                    throw new ArgumentException(string.Format("EventToCommandBehavior: Can't register the '{0}' event.", EventName));
                }
                MethodInfo methodInfo = typeof(EventToCommandBehavior).GetTypeInfo().GetDeclaredMethod("OnEvent");
                eventHandler = methodInfo.CreateDelegate(eventInfo.EventHandlerType, this);
                eventInfo.AddEventHandler(AssociatedObject, eventHandler);
            }
    
            void DeregisterEvent(string name)
            {
                if (string.IsNullOrWhiteSpace(name))
                {
                    return;
                }
    
                if (eventHandler == null)
                {
                    return;
                }
                EventInfo eventInfo = AssociatedObject.GetType().GetRuntimeEvent(name);
                if (eventInfo == null)
                {
                    throw new ArgumentException(string.Format("EventToCommandBehavior: Can't de-register the '{0}' event.", EventName));
                }
                eventInfo.RemoveEventHandler(AssociatedObject, eventHandler);
                eventHandler = null;
            }
    
            void OnEvent(object sender, object eventArgs)
            {
                if (Command == null)
                {
                    return;
                }
    
                object resolvedParameter;
                if (CommandParameter != null)
                {
                    resolvedParameter = CommandParameter;
                }
                else if (Converter != null)
                {
                    resolvedParameter = Converter.Convert(eventArgs, typeof(object), null, null);
                }
                else
                {
                    resolvedParameter = eventArgs;
                }
    
                if (Command.CanExecute(resolvedParameter))
                {
                    Command.Execute(resolvedParameter);
                }
            }
    
            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);
            }
        }
    
    }
    

    here is the 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:local="clr-namespace:Behaviour"
                xmlns:behavior="clr-namespace:Behaviors"
                 x:Class="Behaviour.MainPage">
    
        <StackLayout>
            <!-- Place new controls here -->
            <Label Text="Welcome to Xamarin.Forms!" 
               HorizontalOptions="Center"
               VerticalOptions="CenterAndExpand" />
            <Switch>
                <Switch.Behaviors>
                    <behavior:EventToCommandBehavior
                        EventName="Toggled" Command="OutputCommand"></behavior:EventToCommandBehavior>
                </Switch.Behaviors>
            </Switch>
        </StackLayout>
    
    </ContentPage>
    

    And in View Model

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows.Input;
    using Xamarin.Forms;

            namespace Behaviour.ViewModel
            {
                public class MainPageViewModel
                {
    
                    public ICommand OutputCommand { private set; get; }
    
                    public MainPageViewModel()
                    {
    
                        OutputCommand = new Command(DoThat);
    
                    }
    
                    public void DoThat()
                    {
                        var t = 0;
                        t = 4;
    
                    }
    
                }
            }
    

    Thanks

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    Going to need to see your code if you want people to help with your code.
    Please be sure to use markdown so the forum doesn't try to render your code and XAML

  • siaelenisiaeleni Member ✭✭

    Sure,I posted the code

  • siaelenisiaeleni Member ✭✭

    Any idea?

Sign In or Register to comment.