Zach R
Zach R

Reputation: 181

Connecting RoutedUICommand Namespace to WPF (VB.NET)

I am trying to create a custom CommandBinding, I've decided to put it into its own class so I may add more down the road.

XAML

<Window x:Name="frmWPFtest" x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:self="clr-namespace:WPFtesting.CustomCommands"
    xmlns:local="clr-namespace:WPFtesting"
    mc:Ignorable="d"
    Title="WPF Testing" Height="800" Width="800" MinWidth="800" MinHeight="800">
<Window.CommandBindings>
 <CommandBinding Command="self:cmdExit" CanExecute="CommonCommandBinding_CanExecute" />
</Window.CommandBindings>

Command Class

Namespace CustomCommands

Public Class cCustCmds
    Public cmdExit As New RoutedUICommand("Exit", 
      "Exit", 
      GetType(MainWindow),
      New InputGestureCollection(New KeyGesture(Key.F4, ModifierKeys.Shift)))
End Class

End Namespace

When using self:cmdExit I get a CommandConvertor cannot convert System.String error, and when using self:cCustCmds.cmdExit I get a Name "cCustCmds" does not exist in "WPFtesting.CustomCommands"error.

Is there a specific way to make a class that contains Commands in VB? I have found literally no documentation for anything related to VB, all C#

Upvotes: 0

Views: 185

Answers (1)

Mikael Koskinen
Mikael Koskinen

Reputation: 12916

Based on this article, CommandBindings defined in XAML must point to methods which are defined in the MainWindow:

The reason is, the current WPF version's XAML does not allow us to bind event handlers in this way. The event handlers must be defined in the code-behind file inside the MainWindow class. I don't know if this is a bug, an accidently left out feature, or if we are not even supposed to use this functionality, but this stops us from defining a centralized location for handling all commands' Executed and CanExecute events.

One option is to define the CommandBindings in code:

Class MainWindow
    Private Sub MainWindow_OnLoaded(sender As Object, e As RoutedEventArgs)

        Dim openCmdBinding As New CommandBinding(
            ApplicationCommands.Open, Sub(o, args) MyCommands.MyCommandExecute())

        Me.CommandBindings.Add(openCmdBinding)

    End Sub
End Class

Public Class MyCommands

    Public Shared Sub MyCommandExecute()
        MessageBox.Show("test")
    End Sub

End Class

With the following XAML:

<Grid>
    <Menu DockPanel.Dock="Top">
        <MenuItem Header="File">
            <MenuItem Command="ApplicationCommands.Open"/>
        </MenuItem>
    </Menu>
</Grid>

We get the following result:

WPF VB.NET CommandBindings

Another option is what Andy is referencing in his comment:

  1. Create a ViewModel for your Window.
  2. Define Commands inside the ViewModel
  3. Bind your Window's events into the commands.

For more information: https://social.technet.microsoft.com/wiki/contents/articles/28738.using-icommand-with-mvvm-pattern.aspx

Upvotes: 1

Related Questions