0

I have a user control (a modernTab, provded by modernui) that has a style applied to it, as is specified in a resource dictionary (that again came with modernui).

That's fine, styling for this app is provided through some default resources in the App.xaml file that look like this:

<ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="/FirstFloor.ModernUI;component/Assets/ModernUI.xaml" />
    <ResourceDictionary Source="/FirstFloor.ModernUI;component/Assets/ModernUI.Light.xaml"/>
</ResourceDictionary.MergedDictionaries>

That's well and good. However, I want to override the link style I am using for a specific instance of a modernTab. So in my XAML, I'm trying to do it like this:

<mui:ModernTab ListWidth="Auto" 
               Layout="List" 
               Links ="{Binding MyViewModelLinks}">
    <mui:ModernTab.Resources>
        <Style TargetType="ListBoxItem">
            <Setter Property="Foreground" Value="Black" />
            <Setter Property="Background" Value="Yellow" />
        </Style>
    </mui:ModernTab.Resources>
</mui:ModernTab>

Now, I know from looking at the source that down inside the guts of a modernTab control it's got a bunch of ListBoxItems - these are what I want to change the style on.

What I don't get is why my "local" style isn't going down and overriding for this specific instance. Any ideas?

I tried defining my style override in App.xaml (even though I don't really want it to be global) and it didn't work. Clearly I'm missing something.

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Coopernick
  • 229
  • 2
  • 17
  • In the `ControlTemplate` of `mui:ModernTab`, there is a [`ListBox` with `ListBox.ItemContainerStyle`](https://github.com/firstfloorsoftware/mui/blob/cbd78931b5ffd1a77c8a82a423100e11015203c2/1.0/FirstFloor.ModernUI/Shared/Themes/ModernTab.xaml#L21) being set. I think this takes precedence over an implicit `ListBoxItem` style. The whole construct doesn't look very flexible to me, so think twice before you try to replace that style... – grek40 Dec 14 '16 at 12:04

2 Answers2

2

What you are doing here is not overriding default style of ModernTab but specifying resources of a particular instance, the style is still taken from ModernTab.xaml

What you need to do here is to specify inline style for your instance of ModernTab:

<mui:ModernTab ...>
    <mui:ModernTab.Style>
        <Style TargetType="mui:ModernTab">
            <!------- Full ModernTab Style ----->
        </Style>
</mui:ModernTab.Style>

This inline style will override the default. The bad news is that you cannot create a style based on default ModernTab style and just tweak small details because the default style does not have a name (x:Key). But you can copy the whole style, change whatever you want in it, and use it instead. You should probably put it in a resource file and then use it on your ModernTab instance like this:

<mui:ModernTab Style={StaticResource MyAwesomeStyle} .../>

Hope this helps

Dima Ogurtsov
  • 1,487
  • 1
  • 10
  • 18
  • 1
    It is possible to create a style based on default ModernTab style by using BasedOn="{StaticResource {x:Type mui:ModernTab}}". When implicit style (without x:Key) is declared in a resource dictionary, WPF automatically uses the style's TargetType as the key. – Pavel Dec 14 '16 at 12:01
  • 1
    @Pavel Awesome! I knew the implicit key stuff, but I did not know you could reference the style using the implicit key. Actually makes a lot of sense, thanks! – Dima Ogurtsov Dec 14 '16 at 12:18
  • @Pavel Is that correct? I have a declaration like: – Coopernick Dec 15 '16 at 04:34
1

You need to "override" the ItemContainerStyle of the ListBox in the ModernTab. This should do the trick:

    <mui:ModernTab ListWidth="Auto" 
               Layout="List" 
               Links ="{Binding MyViewModelLinks}">
        <mui:ModernTab.Resources>
            <Style TargetType="ListBox">
                <Setter Property="ItemContainerStyle">
                    <Setter.Value>
                        <Style TargetType="ListBoxItem">
                            <Setter Property="Foreground" Value="Black" />
                            <Setter Property="Background" Value="Yellow" />
                        </Style>
                    </Setter.Value>
                </Setter>
            </Style>
        </mui:ModernTab.Resources>
    </mui:ModernTab>
mm8
  • 163,881
  • 10
  • 57
  • 88
  • Ok, yeah, that does work! I don't understand why though! Why do I have to specify the listbox, then go down the tree and set the ListBoxItem style? Why can't I just set the ListBoxItem style directly? – Coopernick Dec 15 '16 at 03:38
  • 1
    Because the ListBox in the default ControlTemplate of the ModernTab sets an ItemContainerStyle for the ListBox which means that this one will take take precedence and be applied over of the implicit ListBoxItem style that you specify as a resource of the ModernTab. This is how the lookup of styles work. – mm8 Dec 15 '16 at 06:27