Note that there are some explanatory texts on larger screens.

plurals
  1. POWPF - Coupling a GlobalResource to a ViewModel
    primarykey
    data
    text
    <p>I have a WPF application with a <a href="http://www.codeproject.com/KB/WPF/wpf_notifyicon.aspx" rel="nofollow">NotifyIcon</a> defined in a ResourceDictionary that is added to Application.Current.Resources on App start.</p> <p>I am using the MVVM-Light framework and I want to bind the Command properties of a ContextMenu.MenuItems on the NotifyIcon to a public RelayCommand defined in a ViewModel.</p> <p>I am comfortable with coupling a View to a ViewModel but how to I couple a Global Resource to a ViewModel?</p> <p>Here is my attempt at getting this to work, just not sure if I'm on the correct lines or not...</p> <p>When I run this code I get an error stating "Cannot find resource named 'Locator'. Resource names are case sensitive." This originates from the DataContext binding on the TaskBarIcon tag in NotificationIconResources.xaml</p> <p>SingleInstanceManager ensures just one instance can be created</p> <pre><code> 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); } } </code></pre> <p>ControllerApp replaces App.xaml and App.xaml.cs</p> <pre><code>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) { } } </code></pre> <p>NotificationIconResources.xaml is the resource dictionary defining the NotifyIcon</p> <pre><code>&lt;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"&gt; &lt;tb:TaskbarIcon x:Key="ItemNotifyIcon" IconSource="/Controller;component/Images/ItemRunning.ico" IsNoWaitForDoubleClick="True" ToolTipText="Item is running" DataContext="{Binding NotifyIcon, Source={StaticResource Locator}}"&gt; &lt;tb:TaskbarIcon.ContextMenu&gt; &lt;ContextMenu&gt; &lt;MenuItem Header="Open Control Panel" /&gt; &lt;Separator /&gt; &lt;MenuItem Header="Start Item" Command="{Binding Path=StartServiceCommand}" /&gt; &lt;MenuItem Header="Pause Item" /&gt; &lt;MenuItem Header="Stop Item" Command="{Binding Path=StopServiceCommand}" /&gt; &lt;Separator /&gt; &lt;MenuItem Header="Close" /&gt; &lt;/ContextMenu&gt; &lt;/tb:TaskbarIcon.ContextMenu&gt; &lt;/tb:TaskbarIcon&gt; &lt;/ResourceDictionary&gt; </code></pre> <p>NotifyIconViewModel contains the RelayCommands I want to bind to</p> <pre><code> /// &lt;summary&gt; /// This class contains properties that the NotifyIcon View can data bind to. /// &lt;para&gt; /// Use the &lt;strong&gt;mvvminpc&lt;/strong&gt; snippet to add bindable properties to this ViewModel. /// &lt;/para&gt; /// &lt;para&gt; /// You can also use Blend to data bind with the tool's support. /// &lt;/para&gt; /// &lt;para&gt; /// See http://www.galasoft.ch/mvvm/getstarted /// &lt;/para&gt; /// &lt;/summary&gt; public class NotifyIconViewModel : ViewModelBase { private ServiceController sc; public string Welcome { get { return "Welcome to MVVM Light"; } } /// &lt;summary&gt; /// Initializes a new instance of the NotifyIconViewModel class. /// &lt;/summary&gt; public NotifyIconViewModel() { if (IsInDesignMode) { // Code runs in Blend --&gt; 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( () =&gt; this.OnStartServiceCommand(), () =&gt; (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( () =&gt; this.OnStopServiceCommand(), () =&gt; (sc.CanStop &amp;&amp; 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(); ////} } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload