【问题标题】:WPF Context menu commands not setting IsEnabled properlyWPF 上下文菜单命令未正确设置 IsEnabled
【发布时间】:2020-01-11 19:41:10
【问题描述】:

我正在尝试实施和使用 WPF“NotifyIcon”项目。

我已经在我的项目中安装了 NuGet 包,并逐字复制了一些文件,而其他文件则以我自己的方式实现。但是,我使用的是 .Net Core 3.0,而不是它最初设计的 .NetFramework。我确实认为它支持.Net Core 3.0

问题是,当我右键单击托盘图标时,“显示命令”和“隐藏命令”菜单项没有正确启用或禁用,即使我测试他们的“CanExecute”方法返回的值与他们的不同显然,“启用”属性设置为(也就是说,“显示窗口”已启用,但其“CanExecute”方法返回false)。

我的更改是使用以下“RelayCommand”类代替“DelegateCommand”:

using System;
using System.Windows.Input;

namespace UserInterface
{
    class RelayCommand : ICommand
    {
        Action targetExecuteMethod;
        Func<bool> targetCanExecuteMethod;
        public event EventHandler CanExecuteChanged = delegate { };

        public RelayCommand(Action executeMethod, Func<bool> canExecuteMethod)
        {
            targetExecuteMethod = executeMethod;
            targetCanExecuteMethod = canExecuteMethod;
        }

        public void Execute(object parameter)
        {
            targetExecuteMethod?.Invoke();
        }

        public bool CanExecute(object parameter)
        {
            if (targetCanExecuteMethod != null)
                return targetCanExecuteMethod();

            if (targetExecuteMethod != null)
                return true;

            return false;
        }

        public void RaiseCanExecuteChanged()
        {
            CanExecuteChanged(this, EventArgs.Empty);
        }
    }
}

类似地,我的“NotifyIconViewModel”是这样的:

using System.Windows;
using System.Windows.Input;

namespace UserInterface
{
    /// <summary>
    /// Provides bindable properties and commands for the NotifyIcon. In this sample, the
    /// view model is assigned to the NotifyIcon in XAML. Alternatively, the startup routing
    /// in App.xaml.cs could have created this view model, and assigned it to the NotifyIcon.
    /// </summary>
    public class NotifyIconViewModel
    {
        /// <summary>
        /// Shows a window, if none is already open.
        /// </summary>
        public ICommand ShowWindowCommand
        {
            get
            {
                return new DelegateCommand
                {
                    CanExecuteFunc = () => Application.Current.MainWindow == null,
                    CommandAction = () =>
                    {
                        Application.Current.MainWindow = new UserInterface.MainWindow();
                        Application.Current.MainWindow.Show();
                    }
                };
            }
        }

        /// <summary>
        /// Hides the main window. This command is only enabled if a window is open.
        /// </summary>
        public ICommand HideWindowCommand
        {
            get
            {
                return new DelegateCommand
                {
                    CommandAction = () => Application.Current.MainWindow.Close(),
                    CanExecuteFunc = () => Application.Current.MainWindow != null
                };
            }
        }


        /// <summary>
        /// Shuts down the application.
        /// </summary>
        public ICommand ExitApplicationCommand
        {
            get
            {
                return new DelegateCommand { CommandAction = () => Application.Current.Shutdown() };
            }
        }
    }
}

其他一切都与项目页面中的完全一样。但为了确定:

NotifyIconResources.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        xmlns:tb="http://www.hardcodet.net/taskbar"
                        xmlns:local="clr-namespace:UserInterface">

    <ContextMenu x:Shared="false" x:Key="SysTrayMenu">
        <MenuItem Header="Show Window" Command="{Binding ShowWindowCommand}"/>
        <MenuItem Header="Hide Window" Command="{Binding HideWindowCommand}"/>
        <Separator/>
        <MenuItem Header="Exit" Command="{Binding ExitApplicationCommand}"/>
    </ContextMenu>

    <tb:TaskbarIcon x:Key="NotifyIcon"
                        IconSource="/Icons/Bulb.ico"
                        ToolTipText="{Binding ToolTipText}"
                        DoubleClickCommand="{Binding ShowWindowCommand}"
                        ContextMenu="{StaticResource SysTrayMenu}">
        <tb:TaskbarIcon.DataContext>
            <local:NotifyIconViewModel/>
        </tb:TaskbarIcon.DataContext>
    </tb:TaskbarIcon>
</ResourceDictionary>

【问题讨论】:

    标签: c# wpf


    【解决方案1】:

    EventHandler CanExecuteChanged中的问题。

    我的什么都不做,项目最初使用的DelegateCommand是这样做的:

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }
    

    使用这个CanExecuteChanged 可以解决问题。 但不能告诉你为什么会这样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-11
      • 2010-10-14
      • 1970-01-01
      • 1970-01-01
      • 2018-11-25
      • 2011-04-19
      相关资源
      最近更新 更多