我有一個在ResourceDictionary中定義的NotifyIcon的WPF應用程序,該應用程序已添加到App start上的Application.Current.Resources。WPF - 將GlobalResource耦合到ViewModel
我正在使用MVVM-Light框架,我想將NotifyIcon上的ContextMenu.MenuItems的Command屬性綁定到ViewModel中定義的公共RelayCommand。
我很喜歡將視圖耦合到ViewModel,但是如何將全局資源耦合到ViewModel?
這是我在得到這個工作,只是不知道如果我在正確的線路或未遂......
當我運行這段代碼,我得到一個錯誤說「無法找到資源名爲' Locator'。資源名稱區分大小寫。「這從在DataContext在NotificationIconResources.xaml在TaskBarIcon標籤綁定起源
SingleInstanceManager確保只有一個實例可以創建
public sealed class SingleInstanceManager : WindowsFormsApplicationBase
{
[STAThread]
public static void Main(string[] args)
{
(new SingleInstanceManager()).Run(args);
}
public SingleInstanceManager()
{
IsSingleInstance = true;
}
public ControllerApp App { get; private set; }
protected override bool OnStartup(StartupEventArgs e)
{
App = new ControllerApp();
App.Run();
return false;
}
protected override void OnStartupNextInstance(StartupNextInstanceEventArgs eventArgs)
{
base.OnStartupNextInstance(eventArgs);
App.MainWindow.Activate();
App.ProcessArgs(eventArgs.CommandLine.ToArray(), false);
}
}
ControllerApp取代的App.xaml和App.xaml.cs
public class ControllerApp : Application
{
public MainWindow window { get; private set; }
bool startMinimized = false;
private TaskbarIcon tb;
public ControllerApp()
: base()
{ }
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
DispatcherHelper.Initialize();
ResourceDictionary dict = new ResourceDictionary();
dict.Source = new Uri("NotificationIconResources.xaml", UriKind.Relative);
Application.Current.Resources.MergedDictionaries.Add(dict);
ViewModel.ViewModelLocator vmLocator = new ViewModel.ViewModelLocator();
Application.Current.Resources.Add("Locator", vmLocator);
window = new MainWindow();
ProcessArgs(e.Args, true);
//initialize NotifyIcon
tb = (TaskbarIcon)FindResource("ItemNotifyIcon");
if (startMinimized)
{
window.WindowState = WindowState.Minimized;
}
window.Show();
}
protected override void OnExit(ExitEventArgs e)
{
base.OnExit(e);
tb.Dispose();
}
public void ProcessArgs(string[] args, bool firstInstance)
{
}
}
NotificationIconResources.xaml是定義NotifyIcon的資源字典
<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">
<tb:TaskbarIcon x:Key="ItemNotifyIcon"
IconSource="/Controller;component/Images/ItemRunning.ico"
IsNoWaitForDoubleClick="True"
ToolTipText="Item is running"
DataContext="{Binding NotifyIcon, Source={StaticResource Locator}}">
<tb:TaskbarIcon.ContextMenu>
<ContextMenu>
<MenuItem Header="Open Control Panel" />
<Separator />
<MenuItem Header="Start Item" Command="{Binding Path=StartServiceCommand}" />
<MenuItem Header="Pause Item" />
<MenuItem Header="Stop Item" Command="{Binding Path=StopServiceCommand}" />
<Separator />
<MenuItem Header="Close" />
</ContextMenu>
</tb:TaskbarIcon.ContextMenu>
</tb:TaskbarIcon>
</ResourceDictionary>
NotifyIconViewModel包含我要綁定到
/// <summary>
/// This class contains properties that the NotifyIcon View can data bind to.
/// <para>
/// Use the <strong>mvvminpc</strong> snippet to add bindable properties to this ViewModel.
/// </para>
/// <para>
/// You can also use Blend to data bind with the tool's support.
/// </para>
/// <para>
/// See http://www.galasoft.ch/mvvm/getstarted
/// </para>
/// </summary>
public class NotifyIconViewModel : ViewModelBase
{
private ServiceController sc;
public string Welcome
{
get
{
return "Welcome to MVVM Light";
}
}
/// <summary>
/// Initializes a new instance of the NotifyIconViewModel class.
/// </summary>
public NotifyIconViewModel()
{
if (IsInDesignMode)
{
// Code runs in Blend --> create design time data.
}
else
{
sc = new ServiceController("Item");
}
}
#region Public Commands
private RelayCommand _startServiceCommand = null;
public RelayCommand StartServiceCommand
{
get
{
if (_startServiceCommand == null)
{
_startServiceCommand = new RelayCommand(
() => this.OnStartServiceCommand(),
() => (sc.Status == ServiceControllerStatus.Stopped));
}
return _stopServiceCommand;
}
}
private void OnStartServiceCommand()
{
try
{
sc.Start();
}
catch (Exception ex)
{
// notify user if there is any error
AppMessages.RaiseErrorMessage.Send(ex);
}
}
private RelayCommand _stopServiceCommand = null;
public RelayCommand StopServiceCommand
{
get
{
if (_stopServiceCommand == null)
{
_stopServiceCommand = new RelayCommand(
() => this.OnStopServiceCommand(),
() => (sc.CanStop && sc.Status == ServiceControllerStatus.Running));
}
return _stopServiceCommand;
}
}
private void OnStopServiceCommand()
{
try
{
sc.Stop();
}
catch (Exception ex)
{
// notify user if there is any error
AppMessages.RaiseErrorMessage.Send(ex);
}
}
#endregion
////public override void Cleanup()
////{
//// // Clean up if needed
//// base.Cleanup();
////}
}
你好約翰,感謝您的答覆。道歉 - 在回答我的問題時,我一定會添加更多細節。我想我已經得到了這個地方,它也遵循你的建議,但是我陷入困境 - 任何機會,你可以查看我剛剛添加的代碼? – Drammy 2011-03-31 12:35:47