Hi there!
I created a simple custom control (Inherited from ContentView) for learing purposes. The control has two custom properties: Text and Command. When I use this custom control with a page test, the property Text works, but Command doesn't.
What is wrong with my code?
Many thank for any kind of help.
This is my custom control (MyCustomControl.xaml):
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ReusableUserControls.MyCustomControl">
<ContentView.Content>
<StackLayout>
<Entry x:Name="myEntry" Placeholder="enter something" />
<Button x:Name="myButton" Text="Ok" />
</StackLayout>
</ContentView.Content>
</ContentView>>
With the following code behind (MyCustomControl.xaml.cs):
using System;
using System.Windows.Input;
using Xamarin.Forms;
namespace ReusableUserControls
{
public partial class MyCustomControl : ContentView
{
public MyCustomControl()
{
InitializeComponent();
//
this.myButton.Clicked += (object sender, EventArgs e) =>
{
Execute(Command);
};
this.myEntry.TextChanged += (object sender, TextChangedEventArgs e) =>
{
Text = e.NewTextValue;
};
}
public static readonly BindableProperty TextProperty =
BindableProperty.Create(nameof(Text),
typeof(string),
typeof(MyCustomControl),
"",
BindingMode.TwoWay,
propertyChanged: (BindableObject bindable, object oldValue, object newValue) =>
{
var thisView = bindable as MyCustomControl;
if (thisView == null) return;
//
thisView.Text = (string)newValue;
});
//
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); this.myEntry.Text = value; }
}
public static readonly BindableProperty CommandProperty =
BindableProperty.Create(nameof(Command),
typeof(ICommand),
typeof(MyCustomControl),
null);
//
public ICommand Command
{
get { return (ICommand)GetValue(CommandProperty); }
set { SetValue(CommandProperty, value); }
}
// Helper method for invoking commands safely
public static void Execute(ICommand command)
{
if (command == null) return;
if (command.CanExecute(null))
{
command.Execute(null);
}
}
}
}
To test MyCustomControl, I created the following page: (CustomControlTestPage.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:ReusableUserControls;assembly=ReusableUserControls"
x:Class="ReusableUserControls.CustomControlTestPage">
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness" iOS="10,20,10,10" Android="10" WinPhone="10" />
</ContentPage.Padding>
<ContentPage.BindingContext>
<local:MyCustomControlViewModel />
</ContentPage.BindingContext>
<StackLayout Spacing="10">
<!-- THE COMMAND ASSIGN TO CUSTOM CONTROL DOESN'T WORK -->
<local:MyCustomControl Text="{Binding Nome}" Command="{Binding ProcessCommmand}" />
<!-- THE COMMAND ASSIGN TO BUTTON'S PAGE WORKS -->
<Button Text="This button works" Command="{Binding ProcessCommand}" />
</StackLayout>
</ContentPage>
Here is the ViewModel class (MyCustomControlViewModel.cs):
namespace ReusableUserControls
{
public class MyCustomControlViewModel : ViewModelBase
{
string _nome;
public string Nome
{
set { SetProperty(ref _nome, value); }
get { return _nome; }
}
public ICommand ProcessCommand { get; set; }
public MyCustomControlViewModel()
{
ProcessCommand = new Command(ProcessCommandExecute);
Nome = "1, 2, 3 testin...";
}
private void ProcessCommandExecute(object obj)
{
// Just to test the command binding
var a = 1;
}
}
}