Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling commands in WPF application without window

Tags:

c#

wpf

xaml

I'm creating a tray application with WPF (using Hardcodet.NotifyIcon.Wpf NuGet package), which will not display any window at startup. The tray icon has a context menu, but I'm having trouble binding commands to the menu items, since there is nothing that can recieve the commands. I've been trying to bind them to the main application, but it does not seem to work, the CanExecute method is not called, so the menu items are disabled.

My App.xaml resource dictionary looks like this:

<ResourceDictionary>
    <ContextMenu x:Key="TrayMenu">
        <MenuItem Header="{x:Static res:AppResources.ContextMenu_AboutLabel}" Command="local:Commands.About" />
        <Separator />
        <MenuItem Header="{x:Static res:AppResources.ContextMenu_ExitLabel}" Command="local:Commands.Exit" /> 
    </ContextMenu>
    <tb:TaskbarIcon x:Key="TaskbarIcon"
        ContextMenu="{StaticResource TrayMenu}"
        IconSource="Application.ico" />
</ResourceDictionary>

The code-behind simply binds:

public partial class App
{
    public App()
    {
        InitializeComponent();
        var aboutBinding = new CommandBinding(Commands.About, AboutExecuted, CommandCanExecute);
        var exitBinding = new CommandBinding(Commands.Exit, ExitExecuted, CommandCanExecute);
        CommandManager.RegisterClassCommandBinding(GetType(), aboutBinding);
        CommandManager.RegisterClassCommandBinding(GetType(), exitBinding);
    }

    private void CommandCanExecute(object sender, CanExecuteRoutedEventArgs e)
    {
        e.CanExecute = true;
    }

    private void AboutExecuted(object sender, ExecutedRoutedEventArgs e)
    {
        Console.WriteLine("About");
    }

    private void ExitExecuted(object sender, ExecutedRoutedEventArgs e)
    {
        Console.WriteLine("Exit");
        Shutdown();
    }
}

I have defined my commands in a public static class like this:

public static class Commands
{
    public static readonly RoutedUICommand About = new RoutedUICommand();
    public static readonly RoutedUICommand Exit = new RoutedUICommand();
}

I don't hit breakpoints in any method except the constructor, so I'm guess this approach is invalid somehow. How am I supposed to do this?

like image 548
carlpett Avatar asked Jan 19 '26 05:01

carlpett


1 Answers

You have to register commands for the correct class. Try to use typeof(Popup) instead of GetType():

CommandManager.RegisterClassCommandBinding(typeof(Popup), aboutBinding);
CommandManager.RegisterClassCommandBinding(typeof(Popup), exitBinding);
like image 97
Michał Komorowski Avatar answered Jan 20 '26 19:01

Michał Komorowski



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!