我已经用ContextMenus
实现了一个弹出激活,当用户右键单击taskbarIcon时,其中有ShowWindowCommand
个MenuItem。当用户单击该窗口时,它将最大化窗口。以下是ContextMenus
的代码:
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>
点击ShowWindowCommand
后,它将调用NotifyIconViewModel
类中的ICommand属性
NotifyIconViewModel.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; }
}
}
现在我想从另一个类中调用ICommand属性,例如:
ServerModule.cs
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_MSIL \ System.Dynamic \ v4.0_4.0.0.0__b03f5f7f11d50a3a \ System.Dynamic。 dll”。跳过的加载符号。模块已优化,调试器选项“ Just My Code”已启用。
线程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)。
答案 0 :(得分:0)
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
是模型的一部分,则必须重新设计应用程序。
答案 1 :(得分:0)
BionicCode 中的解决方案对我有帮助,非常感谢。我只是添加了一个应用程序调度程序,以避免像下面的代码那样cross-thread exception
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);
});
}
}
}