[ACCEPTED]-Using BasedOn Style Property on DynamicResources-xaml

Accepted answer
Score: 17

I think the main reason is sealed objects. If 15 you have a Style hierarchy:

       Style A
      /       \
  Style A1  Style A2

this might not 14 be a difficult scenario. You refer to StyleA using 13 a dynamic resource, so whenever that resource 12 changes, Style A1 and Style A2 should change their BasedOn property. However, once 11 a Style is being used in your application, it 10 becomes a sealed object. Style A becomes immutable.

One 9 workaround you can use is:

  1. Style A needs to change.
  2. Create a new Style object that is going to be the new Style A resource.
  3. Create a new version of Style A1 and Style A2. You'd need to write a copy procedure that makes copies of all the Setters, Resources, etc. Set the BasedOn to the new version of Style A.
  4. Update the resources collection so that the three new styles are in there.

{DynamicResource StyleA1} and {DynamicResource StyleA2} should now 8 pick up the fact that those resources changes 7 (from step 4) and update any references 6 automatically.

Note that this is a very simple 5 scenario. Real world style hierarchies can 4 be more complex, especially if they are 3 spread across multiple files and come from 2 merged dictionaries.

Hope I understood your 1 problem and helped out.

Score: 16

I've found that since you can't use BasedOn on 8 a DynamicResource, you can "convert" the DynamicResource to StaticResource by merging 7 the ResourceDictionary holding your "parent" resources to 6 your current Window/UserControl/whatever. This 5 way you are now able to refer to the resource 4 object (eg. Style) using StaticResource. This way you can use 3 Datatriggers on DynamicResource (through conversion).

Example:

<Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="/MyProject.Styles;component/ButtonStyles.xaml"/>
        </ResourceDictionary.MergedDictionaries>
        [*Your other resources can be put here*]
    </ResourceDictionary>
</Window.Resources>

...

<Button Command="{Binding MyCommandInViewModel, RelativeSource={RelativeSource AncestorType=Window}}">
    <Button.Style>
        <Style BasedOn="{StaticResource StyleFromButtonStyles}" TargetType="Button">
            <Style.Triggers>
                <DataTrigger Binding="{Binding SomeBool}" Value="True">
                    <Setter Property="Button.Content" Value="{StaticResource SomeImage}"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding SomeBool}" Value="False">
                    <Setter Property="Button.Content" Value="{StaticResource SomeOtherImage}"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Button.Style>
</Button>

Hence 2 Datatriggers are applied to a button styled in an imported 1 ResourceDictionary.

Hope this helps!

More Related questions