Hello.
I'm trying to create a custom control with Xaml and a ViewModel that you can assign a custom command to in the Xaml page that uses it. For example, I have a login page that uses a keypad control, and when a user clicks Enter, I want a command called in the login page. Unfortunately, I can't find documentation for how to do this.
Any help would be much appreciated!
Relevant code below:
Keypad.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="Project.Controls.Keypad">
<Grid
HorizontalOptions="Center"
VerticalOptions="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- Internal Grid for top row of items -->
<Grid Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Frame Grid.Column="0" OutlineColor="Accent">
<Label Text="{Binding DisplayText}" />
</Frame>
</Grid>
<Button Text="1" Command="{Binding AddCharCommand}" CommandParameter="1" Grid.Row="1" Grid.Column="0" />
<Button Text="2" Command="{Binding AddCharCommand}" CommandParameter="2" Grid.Row="1" Grid.Column="1" />
<Button Text="3" Command="{Binding AddCharCommand}" CommandParameter="3" Grid.Row="1" Grid.Column="2" />
<Button Text="4" Command="{Binding AddCharCommand}" CommandParameter="4" Grid.Row="2" Grid.Column="0" />
<Button Text="5" Command="{Binding AddCharCommand}" CommandParameter="5" Grid.Row="2" Grid.Column="1" />
<Button Text="6" Command="{Binding AddCharCommand}" CommandParameter="6" Grid.Row="2" Grid.Column="2" />
<Button Text="7" Command="{Binding AddCharCommand}" CommandParameter="7" Grid.Row="3" Grid.Column="0" />
<Button Text="8" Command="{Binding AddCharCommand}" CommandParameter="8" Grid.Row="3" Grid.Column="1" />
<Button Text="9" Command="{Binding AddCharCommand}" CommandParameter="9" Grid.Row="3" Grid.Column="2" />
<Button Text="⇦" Command="{Binding DeleteCharCommand}" Grid.Row="4" Grid.Column="0" BorderWidth="0" />
<Button Text="0" Command="{Binding AddCharCommand}" CommandParameter="0" Grid.Row="4" Grid.Column="1" />
<!-- The enter button -->
<Button Text="Enter"
Command="{Binding EnterCommand}"
Grid.Row="4" Grid.Column="2" />
</Grid>
</ContentView>
Keypad.xaml.cs
using Xamarin.Forms;
using Project.ViewModels;
namespace Project.Controls
{
public partial class Keypad : ContentView
{
public Keypad()
{
InitializeComponent();
BindingContext = new KeypadViewModel();
}
}
}
KeypadViewModel.cs
using System;
using System.Windows.Input;
using Xamarin.Forms;
using Project.Core.Client.ApplicationModel;
using Project.Core.Services;
using Project.Core.ValueItems;
namespace Project.ViewModels
{
public class KeypadViewModel : ContentView
{
public KeypadViewModel()
{
this.EnterCommand = new Command((nothing) => {
if (KeypadEnterCommandProperty != null) {
KeypadEnterCommand.Execute(this.InputString);
}
});
}
/// <summary>
/// The keypadenter command property.
/// </summary>
public static readonly BindableProperty KeypadEnterCommandProperty = BindableProperty.Create<KeypadViewModel, ICommand>(p => p.KeypadEnterCommand, null);
/// <summary>
/// Gets or sets the keypadenter command.
/// </summary>
/// <value>The keypadenter command.</value>
public ICommand KeypadEnterCommand {
get { return (ICommand)GetValue(KeypadEnterCommandProperty); }
set { SetValue(KeypadEnterCommandProperty, value); }
}
/// <summary>
/// Gets the enter command.
/// </summary>
/// <value>The enter command.</value>
public ICommand EnterCommand{ get; protected set; }
}
}
ClockInPage.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:Project.Converters;assembly=Project"
xmlns:controls="clr-namespace:Project.Controls;assembly=Project"
x:Class="Project.Pages.ClockInPage"
Title="Clock In"
Padding="10, 40, 10, 10"
>
<!-- Trying to add the command here" -->
<controls:Keypad
x:Name="Keypad"
KeypadEnterCommand="{Binding KeypadEnterCommand}"></controls:Keypad>
</ContentPage>
ClockInPage.xaml.cs
using System;
using Xamarin.Forms;
using Project.ViewModels;
namespace Project.Pages
{
public partial class ClockInPage : ContentPage
{
public ClockInPage()
{
InitializeComponent();
BindingContext = new ClockInViewModel();
}
}
}
ClockInViewModel.cs
using System.Collections.Generic;
using System.Windows.Input;
using Xamarin.Forms;
using Project.Core.Client.ApplicationModel;
using Project.Core.Entities.People;
using Project.Core.Services;
using Project.Core.ValueItems;
namespace Project.ViewModels
{
public class ClockInViewModel : BaseViewModel
{
/// <summary>
/// Gets the keypad enter command.
/// </summary>
/// <value>The keypad enter command.</value>
public ICommand KeypadEnterCommand{ get; private set; }
public ClockInViewModel()
{
KeypadEnterCommand = new Command(() => {
// I want to enter here.
});
}
}
}