Creating default style for custom control

10,192

Solution 1

If you create a style without a dictionary key, it will style all objects of the type you specify within the scope that you import your style dictionary (if you specify it in a Window.Resources, it will have scope for that Window... if you specify it in App.xaml... you get the picture).

  <Style TargetType="{x:Type Button}">
    <Setter Property="FontFamily" Value="Times New Roman" />
    <Setter Property="FontSize" Value="30" />
    <Setter Property="FontWeight" Value="Bold" />
    <Setter Property="Background" Value="#FFCA5132" />
  </Style>

This will give them all the same style.

This is a very powerful feature. It allows you to style any object, not just UI elements. You can style, say, one of your data entities like a "Person" object and when those elements are used visually, like databinding a list of type Person to a ListView, all of them will be styled how you specified, even though they are not natively UI elements. This is how WPF can be "lookless" about its controls.

Solution 2

Did you set this in the static constructor?

DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomType), new FrameworkPropertyMetadata(typeof(MyCustomType)));

Also, is the Key of your resource Style equal to your custom control's Type?

It mustn't have some other Key set, even with TargetType set to your control.

The Assembly should also be marked with the following attribute:

[assembly: ThemeInfo(
    //where theme specific resource dictionaries are located
    //(used if a resource is not found in the page, 
    // or application resource dictionaries)
    ResourceDictionaryLocation.None, 

    //where the generic resource dictionary is located
    //(used if a resource is not found in the page, 
    // app, or any theme specific resource dictionaries)
    ResourceDictionaryLocation.SourceAssembly 
)]
Share:
10,192
Admin
Author by

Admin

Updated on June 26, 2022

Comments

  • Admin
    Admin about 2 years

    Im currently creating a custom control (based on the WPF DataGrid). What i would like to do is to set default styling on the datagrid. Currently im setting the Style property which works. But my problem arrises when i create a style to change fx. the background color in the main applications app.xaml. Then all my "default" styling is lost and the DataGrid looks all standard only with the background property set.

    I have tried using OverrideMetadata on each of the properties on the grid that i want to apply a default value to but with no luck. I also tried setting each property in the constructor but because of property precedence the styles from the main application then never is applied.

    Any ideas?

    Thanks in advance

  • Admin
    Admin almost 15 years
    The problem is that the default style i have created already is in the grid's resource dictionary without. The problem is that in my default style for i have: <Style TargetType="DataGrid"> <Setter Property="Background" Value="Black"/> <Setter Property="Foreground" Value="Yellow"/> </Style> Now if i create a new style in the app.xaml in my main app: <Style TargetType="DataGrid"> <Setter Property="Background" Value="Green"/> </Style> The background will not be green because the default style in the grid resource dictionary will have precedence
  • Admin
    Admin almost 15 years
    There must be some way to add default values to each property on the datagrid so that not all my styles will be overriden when a new style is set on the control?
  • Anderson Imes
    Anderson Imes almost 15 years
    You'd have to create another style with the BasedOn attribute set to "DataGrid" and override those few things you want to override for that particular instance.
  • Admin
    Admin almost 15 years
    Hey kek444 I have tried that yes, and when i include the code nothing appears when the grid is rendered (just an empty space where the grid shoud be). Im currently trying to get the BasedOn custom style to work.
  • Kenan E. K.
    Kenan E. K. almost 15 years
    Additional info in answer provided.
  • Admin
    Admin almost 15 years
    I actually didnt have the key set to the type of my control. I have corrected that but still i get an empty area where the control should appear. I have placed the style in the themes/generic.xaml file and added the [assembly: ThemeInfo(ResourceDictionaryLocation.SourceAssembly, ResourceDictionaryLocation.SourceAssembly)] tag to the assemblyinfo file. Could this have anything to do with it?
  • gregsdennis
    gregsdennis over 14 years
    You need to 1) set the default style in Themes/Generic.xaml, with no x:Key on the Style but with the TargetType set 2) set the DefaultStyleKeyProperty.OverrideMetadata statement in the controls static constructor as above 3) you don't need to do anything in the assembly ThemeInfo as above
  • Mark Mullin
    Mark Mullin over 13 years
    Note carefully the phrase "Without a dictionary key"! Just went round on this myself - prototype was using keyed styles, forgot to remove the key when I added the new control to the baseline - presence of a key means it won't ever act as a default style - so, +1
  • Oliver
    Oliver over 13 years
    brilliant I couldn't understand why my control had no template... the ThemeInfo in the AssemblyInfo solved the issue.