tags:

views:

2498

answers:

2

I've been trying to figure out how to organize my ResourceDictionary files for reuse and sharing with other members of my team.

I keep coming across "Generic.xaml", but if I look on MSDN for Generic.xaml or just do a Google search, I only seem to get blog posts and forum questions that happen to mention it--I can't seem to hit upon anything really authoritative and clear.

What is the difference between Generic.xaml and MyRandomlyNamedResourceDictionary.xaml? It seems like either way, I have to reference ResourceDictionaries stored in libraries with the Source attribute. E.g.,:

<Application.Resources>
    <ResourceDictionary
        Source="/CommonLibraryWpfThemes;component/Themes/Generic.xaml"
</Application.Resources>

So what advantage does Generic.xaml provide exactly? Does it have any purpose if I'm not trying to give my application multiple "looks" (i.e., if I have only one theme)?

Thanks!

+9  A: 

For a generic.xaml file (case insensitive) to be something special, two conditions must be met:

  • It must be in the Themes sub-root folder in the project
  • The assembly must be marked with the ThemeInfoAttribute (usually in AssemblyInfo.cs)

Then it serves as the default lookup location for any default styles you wish to apply to your Controls. Note also that for a style to be the default it must declare both its TargetType and x:Key as the Type of Control which is to be styled.

If you wish to add entire themes and theme switching to your application, that is accomplished with some coding, this technique merely defines the default resource dictionary.

kek444
Can you clarify what you mean by "default styles"? Does this mean that all buttons would automatically take on a style whose TargetType is "Button"? Or do I still need to reference the `x:Key` by writing `<Button Style="{StaticResource MyButtonStyle}" />`? What happens if the ResourceDictionary contains more than one Style whose TargetType is "Button"? Thanks.
DanM
One other question to help me get my head around this: is Generic.xaml the WPF equivalent of a CSS file that defined the default look of different elements, e.g., `h1 {color:#00ff00}`?
DanM
Yes, the default style would apply without explicitly referencing the key, and two identical styles would give the error that there are two identical keys in the dictionary. And yes, you could think about it that way, regarding default behaviour.
kek444
+6  A: 

Every Control in WPF has a default Style that provides, among other things, the Control's default ControlTemplate. WPF looks for the default style in a special resource dictionary in the Themes folder in the same assembly as the control. The key for the default style is provided by the Control.DefaultStyleKey dependency property, the default value of which is overriden in each sub-class of Control.

The name of the resource dictionary depends on the current Windows theme e.g. on Vista using the Aero theme, the dictionary is called Aero.NormalColor.xaml, on XP using the default theme it is Luna.NormalColor.xaml. If the style is not found in the theme dictionary, it looks in Generic.xaml i.e for controls whose look doesn't depend on the theme.

This only applies to any custom controls you have defined i.e. classes derived from Control, directly or indirectly. You can change the default style for a standard control by deriving from it and calling DefaultStyleKeyProperty.OverrideMetadata in the static constructor, but you then have to supply the full style including ControlTemplate.

Note that you can tell WPF to look in an external assembly for your default style by using the ThemeInfo attribute. The external assembly must be named ..dll e.g. PresententationFramework.Aero.dll.

Phil Devaney
Thanks, Phil. So are you saying that if I just wanted to provide a new ControlTemplate for a normal Button control (i.e., not write my own special class that derives from Button), this would not be considered part of a "theme"?
DanM
Yes, if you just want to re-template or re-style a standard control, then you use the normal Resources element at UserControl/Window/Application/Whatever level. You can use a style with an implicit key (http://msdn.microsoft.com/en-us/library/ms750613.aspx#stylesimplicitkeys) to change all the controls of a certain type.
Phil Devaney