Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何从另一个类调用ICommand属性_C#_Wpf_Mvvm - Fatal编程技术网

C# 如何从另一个类调用ICommand属性

C# 如何从另一个类调用ICommand属性,c#,wpf,mvvm,C#,Wpf,Mvvm,我已经用ContextMenus实现了一个弹出式激活,每当用户右键单击taskbarIcon时,它都有ShowWindowCommandMenuItems。当用户点击它时,它会最大化窗口。下面是上下文菜单的代码: NotifyIcon.xaml <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x=

我已经用
ContextMenus
实现了一个弹出式激活,每当用户右键单击taskbarIcon时,它都有
ShowWindowCommand
MenuItems。当用户点击它时,它会最大化窗口。下面是
上下文菜单的代码:

NotifyIcon.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:MyProject.ViewModels">

    <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="/tg_shield_copy.ico"
                    ToolTipText="MyProject"
                    DoubleClickCommand="{Binding ShowWindowCommand}"
                    ContextMenu="{StaticResource SysTrayMenu}">

        <tb:TaskbarIcon.DataContext>
            <local:NotifyIconViewModel/>
        </tb:TaskbarIcon.DataContext>
    </tb:TaskbarIcon>

</ResourceDictionary>
现在我想从另一个类调用ICommand属性,例如:

ServerModule.cs

 public class NotifyIconViewModel : BootstrapperBase
    {
        /// <summary>
        /// Shows a window, if none is already open.
        /// </summary>
        public ICommand ShowWindowCommand
        {
            get
            {
                return new DelegateCommand
                {
                    CanExecuteFunc = () => Application.Current.MainWindow == null,
                    CommandAction = () =>
                    {
                        DisplayRootViewFor<ShellViewModel>();
                    }
                };
            }
        }

        /// <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() };
            }
        }
    }

    /// <summary>
    /// Simplistic delegate command for the demo.
    /// </summary>
    public class DelegateCommand : ICommand
    {
        public System.Action CommandAction { get; set; }
        public Func<bool> CanExecuteFunc { get; set; }

        public void Execute(object parameter)
        {
            CommandAction();
        }

        public bool CanExecute(object parameter)
        {
            return CanExecuteFunc == null || CanExecuteFunc();
        }

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }
       
    }
 public class ServerModule : NancyModule
{
   public ServerModule()
   {
      Post ("/Message", (args) =>
      {
        // Call ShowWindowCommand from here
      }
   }
}
我的问题是,如何从
ServerModule.cs
类调用ICommand属性,该类与我在
NotifyIcon.xaml中使用绑定命令调用的类相同

更新

已在使用代码建议,但出现异常

“MyProject.exe”(CLR v4.0.30319:MyProject.exe):已加载“C:\WINDOWS\Microsoft.Net\assembly\GAC\U MSIL\System.Dynamic\v4.0\U 4.0.0.0\UUUU b03f5f7f11d50a3a\System.Dynamic.dll”。已跳过加载符号。模块已优化,并且调试器选项“仅我的代码”已启用

线程0x550c已退出,代码为0(0x0)

线程0x52e4已退出,代码为0(0x0)

引发异常:WindowsBase.dll中的“System.InvalidOperationException”

引发异常:WindowsBase.dll中的“System.InvalidOperationException”

线程0x43d8已退出,代码为0(0x0)

引发异常:WindowsBase.dll中的“System.InvalidOperationException”

线程0x52b8已退出,代码为0(0x0)

线程0x333c已退出,代码为0(0x0)


ServerModule
需要对公开所需命令的对象实例的引用:

public class ServerModule : NancyModule
{
   private NotifyIconViewModel CommandViewModel { get; }

   public ServerModule(NotifyIconViewModel commandViewModel)
   {
      this.CommandViewModel = commandViewModel;
      Post ("/Message", (args) =>
      {
        this.CommandViewModel.ShowWindowCommand.Execute();
      }
   }
}

若您使用的是MVVM,那个么请确保
ServerModule
是视图或视图模型组件的一个类。否则,您将违反设计模式(因为您的模型将调用其中任何一个)。如果
ServerModule
是模型的一部分,那么您必须重新设计您的应用程序。

来自BionicCode的解决方案帮助我,非常感谢。我只是添加了一个应用程序dispatcher,以避免像下面的代码一样出现
跨线程异常

public class ServerModule : NancyModule
{
   private NotifyIconViewModel CommandViewModel { get; }

   public ServerModule(NotifyIconViewModel commandViewModel)
   {
     this.CommandViewModel = commandViewModel;

     Post ("/Message", (args) =>
     {
       Application.Current.Dispatcher.Invoke(delegate
       {
          CommandViewModel.ShowWindowCommand.Execute (null);
       });
     }
   }
}

您所说的
ServerModule
是视图或视图模型的一个类是什么意思?我认为这一类与
Server
NotifiyIcon
类不同。我已经尝试了你的代码建议,但它不起作用@BionicCodeI get error exception
调用线程无法访问此对象,因为另一个线程拥有它。
这是一个跨线程异常。你可以从后台线程访问UI元素。你知道在哪里吗?您知道在哪一行抛出此异常吗?调试器通常在导致异常的行中断。你能发布那个部分吗?我看不出调试器在哪里换行,但是输出显示了那个异常。顺便说一句,我已经更新了我的帖子@bioniccode。这个问题太广泛了,因为人们可能会采取许多不同的方法,而且鉴于到目前为止的信息,没有明确的路径,特别是考虑到缺乏一个明确的答案。这就是说,尽管命令似乎可以从notify窗口执行,但它实际上更具全局性,因此您可以考虑创建一个
RouteDuicCommand
,并在必要时使用绑定从任何相关上下文调用它。也就是说,将命令本身看作是由
NotifyIconViewModel