9

I'm using Telerik's RadControls for WPF with implicit styling. The following style is defined in Themes/Windows8/Telerik.Windows.Controls.RibbonView.xaml:

<Style TargetType="telerikRibbonView:RadRibbonView" x:Key="RadRibbonViewStyle">
...
</Style>

My own styles and the Telerik default ones get merged like this in the assembly Lib.Windows.Controls in the folder Themes:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="Windows8/Telerik.Windows.Controls.RibbonView.xaml" />        
        <ResourceDictionary Source="MyTheme/TelerikCustomizations.xaml" />

        <ResourceDictionary>
            <!-- avoid optimization -->
            <Style TargetType="{x:Type Rectangle}" />
        </ResourceDictionary>
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

And in TelerikCustomizations.xaml I define the following (empty, for testing purposes) style:

<Style x:Key="MyThemeRadRibbonViewStyle" TargetType="{x:Type telerik:RadRibbonView}" BasedOn="{StaticResource ResourceKey=RadRibbonViewStyle}" />

Which results in the following exception at runtime:

'Provide value on 'System.Windows.Markup.StaticResourceHolder' threw an exception.' Line number '4' and line position '42'. {"Cannot find resource named 'RadRibbonViewStyle'. Resource names are case sensitive."}

Which led me to the following debugging statements in MyView.xaml.cs:

public ShellView()
{
    var baseStyle = FindResource("RadRibbonViewStyle");
    var inherited = FindResource("MyThemeRadRibbonViewStyle");
    InitializeComponent();
}

Now the thing is: The exception is thrown on the second FindResource call. With the exact same message. However the RadRibbonViewStyle is clearly found in the first line of the constructor.

If it matters, the merged dictionary is actually merged in App.xaml a second time.

I'm sure I'm missing something obvious, but I can't figure out what.

App.xaml

<Application x:Class="TestClient.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    StartupUri="Views/ShellView.xaml">
    <Application.Resources>
      <ResourceDictionary>
          <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/Lib.Windows.Controls;component/Themes/MyTheme.xaml" />

              <ResourceDictionary>
                    <!-- added to avoid optimization -->
                    <Style TargetType="{x:Type Rectangle}" />
                </ResourceDictionary>
            </ResourceDictionary.MergedDictionaries>
      </ResourceDictionary>
    </Application.Resources>
</Application>

App.xaml.cs does not overwrite the constructor. In fact it does not do anything.

Update

If I merge the Telerik dictionaries in TelerikCustomizations.xaml instead of merging them in yet another dictionary (MyTheme.xaml), the exception disappears.

However, I'd still like to know why this happens.

cguedel
  • 1,092
  • 1
  • 14
  • 28
  • I think TelerikCustomizations.xaml is not able to find RadRibbonViewStyle in BasedOn="{StaticResource ResourceKey=RadRibbonViewStyle}" – yo chauhan Aug 20 '13 at 14:13
  • Yeah, but why? Themes/Windows8/Telerik.Windows.Controls.RibbonView.xaml gets merged in right before TelerikCustomizations.xaml. – cguedel Aug 20 '13 at 14:14
  • Aren't you missing `Themes` from the source of first resource dictionary? – Rohit Vats Aug 20 '13 at 14:18
  • @RohitVats no, because the dictionary is in the Themes folder. And I think that would generate a compile time error, not a runtime exception. – cguedel Aug 20 '13 at 14:21
  • You can try with `DynamicResource` : `BasedOn="{DynamicResource ResourceKey=RadRibbonViewStyle}"` Or you can merge `RibbonView.xaml` not directly the app.xaml or your merged dictionary but in your `TelerikCustomizations.xaml` and in your app.xaml only refernce `TelerikCustomizations.xaml`. So the point is that `TelerikCustomizations.xaml` and `RibbonView.xaml` should not be "next" to each other in a MergedDictionaries. But your customizations should depend on the ribbon. – nemesv Aug 20 '13 at 14:26
  • @colinsmith Does not seem to work. Added a style without a key to App.xaml and the dictionary where everything gets merged together. still the same exception. – cguedel Aug 20 '13 at 14:27
  • @nemesv Merging the Telerik dictionaries in `TelerikCustomizations.xaml` works. I still want to know why though ;) – cguedel Aug 20 '13 at 14:51

1 Answers1

9

You need to merge in the Windows8/Telerik.Windows.Controls.RibbonView.xaml in your MyTheme/TelerikCustomizations.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="Windows8/Telerik.Windows.Controls.RibbonView.xaml" />
        <ResourceDictionary>
            <Style x:Key="MyThemeRadRibbonViewStyle" TargetType="{x:Type telerik:RadRibbonView}" BasedOn="{StaticResource ResourceKey=RadRibbonViewStyle}" />
        </ResourceDictionary>
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

And now you can use/merge this dictionary wherever you want.

You need to do this because StaticResource is not working between "sister" MergedDictionaries so you cannot reference a resource which was merged on the same level because the StaticResource looks only backwards to the direct parents:

From MSDN:

XAML resource references within a particular resource dictionary must reference a resource that has already been defined with a key, and that resource must appear lexically before the resource reference. Forward references cannot be resolved by a XAML resource reference

But when using MergedDictionaries:

In the resource-lookup sequence, a MergedDictionaries dictionary is checked only after a check of all the keyed resources of the ResourceDictionary that declared MergedDictionaries.

nemesv
  • 138,284
  • 16
  • 416
  • 359
  • So in theory that would also work if you include `Windows8/Telerik.Windows.Controls.RibbonView.xaml` in your App.xaml before the `MyTheme.xaml` but I'm not sure in that. From the documentation it is not clear whether `StaticResource` is not working for direct "sister dictionaries" or it is also not working between "sister dictionary branches"... – nemesv Aug 20 '13 at 15:05
  • Thank you very much, this explains a lot ;) – cguedel Aug 20 '13 at 15:05