Search code examples
c#wpfmenuitemcontroltemplateresourcedictionary

How can code find resource in model that does not have access to user control


I have a UserControl that has MergedDictionaries:

<UserControl.Resources>
  <ResourceDictionary>
     <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="../LimitResources.xaml" />
        <ResourceDictionary Source="../MenuItemTemplateResources.xaml" />
     </ResourceDictionary.MergedDictionaries>
   ...
</UserControl.Resources>

in my Model a Menu is created. I want to access ControlTemplate declared in MenuItemTemplateResources.xaml. The ControlTemplate looks like this

<ControlTemplate x:Key="SubMenuItemCombo" TargetType="MenuItem">
.....
</ControlTemplate>

Model has reference to "main" wpf window of the application (The application is hybrid of Winform and WPF).

Window.FindResource does not find either way:

FindResource("SubMenuItemCombo");
FindResource(new ComponentResourceKey(typeof(MenuItem), "SubMenuItemCombo"));

Any ideas? Thank you.


Solution

  • A more sophisticated approach would be to set the resource as a StaticResource to a property of your ViewModel. You can do this in XAML if you instantiate your ViewModel as a resource, like

    <my:ViewModel x:Key="viewModel" myResource="{StaticResource myResource}"/>
    

    (provided you declare the resource before the ViewModel).

    If this is not possible, you can use a helper component like a Freezable which binds to the ViewModel, takes the resource as a property as above, and sets the required property on the ViewModel.

    This solution is for cases where you want to keep the ViewModel without code dependency on the resource, e.g. in a control library where the resource is not known beforehand.

    Depending on what your application needs, you might also consider setting the resource to a control's CommandParameter and passing it to the ViewModel this way when needed; I sometimes do this with file dialogs, like

    <Button x:Name="OpenButton" Command="{Binding OpenCommand}" CommandParameter="{StaticResource openDialog}">Open File...</Button>
    

    If OpenCommand is an ICommand implementation provided by the ViewModel, then the open dialog would be passed as the "parameter" argument to the ICommand's Execute and CanExecute methods. Instead of a Button, one could use any control which implements ICommandSource.