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