Search code examples
c#wpfwpf-controls

Custom keyboard with key components commands not feeding through


I'm creating a custom on-screen keyboard to keep the appearance consistent within my program. I decided to have each key be a custom component which feeds a command hosted on the Keyboard component through to the button part of the Key. That way I can use the same Key component for the special keys as well.

The Key component works fine when hosted straight on the main window, but when I try to run it through the Keyboard component, the command does not execute.

The intent is to have the letter or number on the Key be added to the Text property of the keyboard. I will deal with special keys later.

Key snippet:

<UserControl
    x:Name="ThisKey"
    >
    <Grid>
        <Button
            Command="{Binding Command, ElementName=ThisKey}"
            CommandParameter="{Binding CommandParameter, ElementName=ThisKey}"
            />
    </Grid>
</UserControl>

Where Command and CommandParameter are defined as:

public ICommand Command
{
    get => (ICommand)GetValue(CommandProperty);
    set => SetValue(CommandProperty, value);
}

public static readonly DependencyProperty CommandProperty = DependencyProperty.Register(
    nameof(Command),
    typeof(ICommand),
    typeof(Key),
    new UIPropertyMetadata(null));

public object CommandParameter
{
    get => GetValue(CommandParameterProperty);
    set => SetValue(CommandParameterProperty, value);
}

public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register(
    nameof(CommandParameter),
    typeof(object),
    typeof(Key),
    new PropertyMetadata(string.Empty));

Within the Keyboard component, I call Keys as follows:

<local:Key
    Command={Binding KeyCommand, RelativeSource={RelativeSource AncestorType=local:Keyboard}}"
    CommandParameter="0"
    />

Where KeyCommand is defined as:

private RelayCommand KeyCommandRelay;
public ICommand KeyCommand
{
    get
    {
        if (KeyCommandRelay == null)
        {
            KeyCommandRelay = new RelayCommand(
                    param => KeyCommand_Executed(param),
                    param => true
                    );
        }
        return KeyCommandRelay;
    }
}
private void KeyCommand_Executed(object param)
{
    //Text is a string property of Keyboard.
    Text += (string)param;
    //This is here to prove to me that the button is pressed, to rule out errors with Text.
    MessageBox.Show((string)param);
}

Placing the Key directly in the window has the command working fine, however it does not execute the command when forming part of the Keyboard.


Solution

  • I realised that I had renamed the command on the keyboard but not renamed it in the XAML. Besides that, I had also typoed it with "KeyButtom" instead of the original name "Keybutton".