1

As I researched ways to specify default values for inherited dependency properties on a custom control, I ended up being more confused than enlightened.

What I found is basically:

I guess I'd be happy if I knew only one of the possibilities, but now I wonder which approach is the best fit under normal circumstances / whether there are significant drawbacks to any of the approaches.

Community
  • 1
  • 1
grek40
  • 13,113
  • 1
  • 24
  • 50

1 Answers1

1

When building Custom Controls there's a clear separation between the abstract model (class) and its representation (Generic.xaml). As always we should keep the view as dumb as possible, but likewise it pays to keep the implementation in the representation layer (and not clutter the model).

The only reason I can think of for overriding the default value in the class, would be when the order of initialization matters. For example, in case the inherited default value would throw an exception during the initialization of your class (before the Generic style would be able to "override" it).

  • Generic XAML: the preferred method, this offers most flexibility. Provides a clear picture of the default implementation (see edit).

  • Method override: As mentioned, when the order of initialization matters. Leads to less clean code.

  • DefaultInitializer: Is used to provide default values for VS designer.

The DefaultInitializer extension is invoked when the user adds an object from the Toolbox to the design surface. Derive from the DefaultInitializer class to configure default initial values for your object.

EDIT - Subclassing Custom Controls

This is another area where separation of concerns pays off, giving you a clear overview.

<Style TargetType="{x:Type local:MyButtonBase}">
    <Setter Property="FontSize" Value="12"/>
    <Setter Property="HorizontalContentAlignment" Value="Center"/>
    <Setter Property="VerticalContentAlignment" Value="Center"/>
</Style>

<Style BasedOn="{StaticResource {x:Type local:MyButtonBase}}"
       TargetType="{x:Type local:MyButton}">
    <!--Override inherited default value-->
    <Setter Property="FontSize" Value="18"/>
    <!--Add default values-->
    <Setter Property="IsDefault" Value="True"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:MyButton}">

                ...

            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
bab7lon
  • 343
  • 1
  • 10
  • 1
    A thought that crossed my mind but which I didn't finish yet: when deriving from framework controls, I am free to chose between the different kinds of value override and it works for all I can tell. But what if I subclass my custom control again... I have to test it, but probably in this case it pays off to use `OverrideMetadata` because defaults from parent `Style` would not necessarily be considered there? – grek40 Feb 24 '17 at 11:37
  • I'd keep it XAML and declare the style for the derived control as ` – bab7lon Feb 24 '17 at 12:45
  • The main thing to keep in mind is that the (default) implementation doesn't really belong in the abstract model. As long as the class can be initiated... – bab7lon Feb 24 '17 at 12:47
  • Accepting it for now, since valuable points are considered. May be worth to merge the aspect of `BasedOn="..."` into the answer part about generic.xaml. – grek40 Feb 24 '17 at 17:19