C
C#13mo ago
cisflex

canvas keydown event binding mvvm

Hello everyone! I am making a .net 6 wpf application and inside the application I am trying to get canvas working with mvvm I can already add items to the canvas en make them move. Also the coloision detection is working. Now the only thing I am struggling with is binding the keydown event to the viewmodel.
3 Replies
Alexicon
Alexicon13mo ago
Welcome to the world of event binding in mvvm with wpf. In order to bind an event to a command in your view model I reccomend using the nuget package: 'Microsoft.Xaml.Behaviors.Wpf' Once you have this package installed in your wpf project you can add the following xaml on any element that has events:
<b:Interaction.Triggers>
<b:EventTrigger EventName="the name of the event you want to bind to">
<b:InvokeCommandAction Command="{Binding the name of your command in your view model}"/>
</b:EventTrigger>
</b:Interaction.Triggers>
<b:Interaction.Triggers>
<b:EventTrigger EventName="the name of the event you want to bind to">
<b:InvokeCommandAction Command="{Binding the name of your command in your view model}"/>
</b:EventTrigger>
</b:Interaction.Triggers>
So to do what you want to do you would install that package, add a xmlns refrence, and add the following to your canvas:
<!--Add xmlns-->
<Window
...
xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
...>

...

</Window>
<!--Add xmlns-->
<Window
...
xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
...>

...

</Window>
<!--Add EventTrigger-->
<Canvas ...>

<b:Interaction.Triggers>
<b:EventTrigger EventName="KeyDown">
<b:InvokeCommandAction
Command="{Binding MyKeyDownCommand}"
PassEventArgsToCommand="True"/>
</b:EventTrigger>
</b:Interaction.Triggers>

...
</Canvas>
<!--Add EventTrigger-->
<Canvas ...>

<b:Interaction.Triggers>
<b:EventTrigger EventName="KeyDown">
<b:InvokeCommandAction
Command="{Binding MyKeyDownCommand}"
PassEventArgsToCommand="True"/>
</b:EventTrigger>
</b:Interaction.Triggers>

...
</Canvas>
I added the 'PassEventArgsToCommand' since I assume you are going to try and detect which keys are being pressed, this will mean in your command method within the view model you can do something like:
public void OnKeyDown(object? args)
{
if (args is KeyEventArgs e)
{
if (e.Key is Key.D)
{
...
}
else if (e.Key is Key.A)
{
...
}
}
}
public void OnKeyDown(object? args)
{
if (args is KeyEventArgs e)
{
if (e.Key is Key.D)
{
...
}
else if (e.Key is Key.A)
{
...
}
}
}
Alexicon
Alexicon13mo ago
note that in order to actually use the key events on the canvas you have to give that canvas the focus which means you have to set the focusable property to true and explicitly give it focus in code, for example:
<Canvas
x:Name="MyCanvas"
Focusable="True">

...

</Canvas>
<Canvas
x:Name="MyCanvas"
Focusable="True">

...

</Canvas>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();

MyCanvas.Focus();
}
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();

MyCanvas.Focus();
}
}
Alternativly you can just use the key down event on say the window instead and avoid this, for example:
<Window
...
xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
...>

<b:Interaction.Triggers>
<b:EventTrigger EventName="KeyDown">
<b:InvokeCommandAction
Command="{Binding MyKeyDownCommand}"
PassEventArgsToCommand="True"/>
</b:EventTrigger>
</b:Interaction.Triggers>

...

</Window>
<Window
...
xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
...>

<b:Interaction.Triggers>
<b:EventTrigger EventName="KeyDown">
<b:InvokeCommandAction
Command="{Binding MyKeyDownCommand}"
PassEventArgsToCommand="True"/>
</b:EventTrigger>
</b:Interaction.Triggers>

...

</Window>
I have a simple working example of all this here: https://github.com/AlexLexicon/Discord.Example.CanvasEventBinding
GitHub
GitHub - AlexLexicon/Discord.Example.CanvasEventBinding
Contribute to AlexLexicon/Discord.Example.CanvasEventBinding development by creating an account on GitHub.
cisflex
cisflexOP13mo ago
Thx it workt !
Want results from more Discord servers?
Add your server