Bind a button command inside a custom control

NicolasFournierNicolasFournier Member ✭✭
edited May 2018 in Xamarin.Forms

Hi everyone !

I'm facing an issue and I can't figure it out. I have a custom control, to simplify it let's say I have a button inside of a frame inside of a frame. I want the command of the button to be bindable and the button is private. So, here is my code :

CustomControl.cs :

public System.Windows.Input.ICommand CommandInButton
    {
        get { return ButtonInFrame.Command; }
        set { ButtonInFrame.Command = value; }
    }

private Button ButtonInFrame;

Myview.xaml : (I'm using Prism)

                <local:FrameButtonImage Grid.Column="0" Grid.Row="0"
                                    ColorInButton="LightBlue"
                                    SourceImageInButton="male.png"
                                    IsSelected="{Binding IsMenSelected}"
                                    CommandInButton="{Binding SelectMenCommand}"
                                    />

MyViewModel.cs : (I'm using Prism)

public DelegateCommand SelectMenCommand { get; private set; }

public MainPageViewModel()
    {
        SelectMenCommand = new DelegateCommand(SelectMen, CanSelectMen);
    }
        private void SelectMen()
    {
        System.Diagnostics.Debug.WriteLine("Hello men");
    }

    private bool CanSelectMen()
    {
        return !IsMenSelected;
    }

I simplify all code above to focus on the problem.

When I'm trying to run on my android emulator, I code the folowing error :

Xamarin.Forms.Xaml.XamlParseException: Position 74:41. Cannot assign property "CommandInButton": Property does not exists, or is not assignable, or mismatching type between value and property

If I create a simple button on my xaml view and bing my command from my view model, it's work. So the problem come from my custom control.
I already try differents things, like

public Command CommandInButton
    {
        get { return (Xamarin.Forms.Command)ButtonInFrame.Command; }
        set { ButtonInFrame.Command = value; }
    }

But I face same error.

Maybe someone know what I am doing wrong ? Thanks !

UPDATE 1

I'm stupid, forgot to create a Bindeable Property. So, now in my CustomControl.cs :

public System.Windows.Input.ICommand CommandInButton
    {
        get { return ButtonInFrame.Command; }
        set { ButtonInFrame.Command = value; }
    }

public static readonly BindableProperty CommandInButtonProperty = 
        BindableProperty.Create(
            propertyName:"CommandInButton",
            returnType: typeof(System.Windows.Input.ICommand),
            declaringType: typeof(CustomControl),
            defaultBindingMode: BindingMode.TwoWay);

private Button ButtonInFrame;

No more errors. But my SelectMen() is never trigger. Any ideas ? Thanks !

Answers

  • NicolasFournierNicolasFournier Member ✭✭

    I found a workaround but I'm sure it's possible to do better. I set my command to be a property of my custom control and add a method to set it to be the command of the button when the command is set.

    CustomControl.cs :

    public System.Windows.Input.ICommand CommandInButton
        {
            get; set;
        }
    
        public static readonly BindableProperty CommandInButtonProperty =
            BindableProperty.Create(
                propertyName: "CommandInButton",
                returnType: typeof(System.Windows.Input.ICommand),
                declaringType: typeof(CustomControl),
                defaultValue: null,
                propertyChanged: CommandInButtonPropertyChanged);
    
        private static void CommandInButtonPropertyChanged(BindableObject bindable, object oldValue, object newValue)
        {
            var control = (CustomControl)bindable;
            control.ButtonInFrame.Command = (System.Windows.Input.ICommand)newValue;
        }
    
Sign In or Register to comment.