HGBRD
HGBRD

Reputation: 89

Apply Style to controls that derives from a certain base class

How to apply style to all children that is based on a certain CustomControl.

Example

A CustomControl

public class SubView : UserControl
{ ... }

A control based on the CustomControl

public partial class MyView : SubView
{ ... }

XAML for MyView

<myLibrary:SubView
    xmlns:myLibrary="....">

<Grid>
    <!--Any content-->
</Grid>
</moduleChrome:SubView>

The parent (the children of this grid is set from code run-time)

<Grid>
    <Grid.Resources>
        <Style TargetType="myLibrary:SubView">
            <Setter Property="MyCustomDependancy" Value="{binding to a shared MyCustomDependancy}"/>
        </Style>
    </Grid.Resources>

    <myLibrary:SubView/>   <!--This will have the shared MyCustomDependancy-->
    <localFolder:MyView/>    <!--But this will not be affected-->
</Grid>

How would one do to let the MyView be affected by the style?

EDIT

The origin of this code is dynamic and fairly complex, but I tried to make the question as generic as possible so as many people as possible could be helped by a possible solution, but I guess I made it too generic. I will probably not be helped by these answers, but I hope someone else will.

Upvotes: 0

Views: 369

Answers (2)

mm8
mm8

Reputation: 169150

This will actually work as expected provided that SubView really is a custom control rather than a UserControl and has a default template defined in Themes/Generic.xaml.

You can confirm this yourself using the following sample code.

Themes/Generic.xaml:

<Style TargetType="local:SubView">
    <Setter Property="Opacity"  Value="0.5" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:SubView}">
                <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
                    <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Controls:

public class SubView : ContentControl
{
    static SubView()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(SubView),
            new FrameworkPropertyMetadata(typeof(SubView)));
    }
}

public class MyView : SubView
{

}

Usage:

<local:SubView>
    <local:SubView.Content>
        <TextBlock>content 1</TextBlock>
    </local:SubView.Content>
</local:SubView>
<local:MyView>
    <local:SubView.Content>
        <TextBlock>content 2</TextBlock>
    </local:SubView.Content>
</local:MyView>

From MSDN: "If you do need to create a new control, the simplest way is to create a class that derives from UserControl. Before you do so, consider that your control will not support templates and therefore will not support complex customization."

https://msdn.microsoft.com/en-us/library/system.windows.controls.usercontrol(v=vs.110).aspx

Upvotes: 1

Tyrrrz
Tyrrrz

Reputation: 2611

Styles only apply to a specific class, they don't get inherited. You can do this, though:

<Style TargetType="{x:Type myLibrary:SubView}">
    <Setter Property="Opacity" Value="0.5"/>
</Style>
<Style TargetType="{x:Type localFolder:MyView}" BasedOn="{StaticResource {x:Type myLibrary:SubView}} />

Upvotes: 1

Related Questions