Overriding some theme styles and properties per module - wpf

I am writing a WPF application using "Prism", and some purchased Grid theme is applied "Xceed Theme." I am designing a huge change required by our customer to give them the option of modifying some properties (like the background of selected row, for example) and this functionality to be available per screen "Module."
So my questions are:
After adding my xceed grid theme source to my App.xaml merged dictionaries, how can I override some of its styles (that I know the keys of) in another xaml file away from app.xaml (possibly by adding BasedOn to the style tag)?
Is it possible to create a custom resource dictionary for each module and add it to the app.xaml merged dictionaries while loading?

You could add the style changes in the main window/control's resources within each module. Then the differences would apply to each module separately.

In my case, I have userd Dynamic Resources. The main project loads the main style. somthing like this :
<FontFamily x:Key="ApplicationFontFamily">Tahoma</FontFamily>
and in my module i have changed it programmatically :
Application.Current.Resources["ApplicationFontFamily"] = new FontFamily("Arial");
it worked for me ;)

Related

WPF: Applying a custom theme (skin) to a custom control

I have an application set up so that I can adjust its skin at run time. I am doing it as follows each time I change the skin:
Uri uri = new Uri("SomeThemeAssembly;component/Themes/StandardTheme.xaml", UriKind.Relative)
Application.Current.Resources.MergedDictionaries.Clear();
ResourceDictionary resource = (ResourceDictionary)Application.LoadComponent(uri);
Application.Current.Resources.MergedDictionaries.Add(resource);
This works fine.
I have also created a custom control with its controltemplate defined in Themes/Generic.xaml using ComponentResourceKeys for the relevant resources, etc
x:Key="{ComponentResourceKey
TypeInTargetAssembly={x:Type local:MyCustomControl},
ResourceId=MyBrush}"
The style of the custom control itself doesnt use a componentresourcekey as I want it to style all instances.
<Style TargetType="{x:Type local:MyCustomControl}">
Again this all works fine and standard controls I have used to compose elements of my custom control are appropriately styled when I change the skin.
However there are a number of custom properties( brushes, widths, etc) on my control that need to be styled to fit in with the skins I am applying.
In examples I have seen using the standard windows themes adding an additional file
Luna.StandardColor.Xaml
for example, to the themes directory of the custom control allows a modified control template to be set and picked up when that particular theme is applied. This won't work for me, as far as I can tell anyway, as my skins are not themes.
Can something similar be achieved when using 'skins' in the manner I have?
Obviously I can add Styles and ControlTemplates to my skin assemblies but this feels wrong especially as there is a standard naming convention across the skin assemblies for resources. So only a single more maintainable style would be required if it could be stored in Themes/StandardTheme.xaml in my custom control's assembly.
Having tried to read around on this subject I have the impression want I want to do is either impossible or will require loads of extra leg work.
Any thoughts appreciated.
In the CustomControls Themes Directory add a MyNewTheme.xaml file that's a resource dictionary that has an implicit style set for your control. Then merge that resource dictionary in with your other one as needed. For example:
Uri uri = new Uri("SomeThemeAssembly;component/Themes/MyNewTheme.xaml", UriKind.Relative)
Uri controlsUri = new Uri("ControlAssembly;component/Themes/MyNewTheme.xaml", UriKind.Relative)
Application.Current.Resources.MergedDictionaries.Clear();
ResourceDictionary resource = (ResourceDictionary)Application.LoadComponent(uri);
Application.Current.Resources.MergedDictionaries.Add(resource);
ResourceDictionary resource = (ResourceDictionary)Application.LoadComponent(controlsUri);
Application.Current.Resources.MergedDictionaries.Add(resource);

Splitting WPF ResourceDictionary

I have a WPF application made up of around seven user controls, each with a variety of different controls on each (textbox, combobox, radio button etc).
Across the entire app I have applied a set of control styles take from the WPF Themes on CodePlex, however I have noticed a bit of a slowdown on the app since applying these styles. The ResourceDictionary containing all my styles weighs in at nearly 300kb in code size.
Would there be a benefit to gain by splitting the styles in to multiple Resource Dictionaries and only merging the styles that each usercontrol requires rather than the all the control styles even if they are not being used.
How does WPF load styles in to memory? When required or is the whole ResourceDictionary loaded in to memory at startup?
When an object is created from XAML (or BAML), the XamlReader deserializes all of the XAML's contents. Every XAML element it finds creates an instance of an object - so the Style elements under the UserControl.Resources element generate Style objects that get added to the user control's resource dictionary at the time the object is deserialized. (It's actually a little more complicated than this, since there are apparently parts of XAML deserialization that are asynchronous, but it's close enough for the purposes of this discussion.)
It's important to understand that Resources is not a static property. Every instance of a user control has its own resource dictionary. If you put 300 styles in the user control's XAML, and you create 100 user controls, you'll be creating 30,000 Style objects. This is true whether you're using merged dictionaries or not.
If your resource dictionary is as huge as you say, by far the best thing to do is to put it into the application's Resources property. That way you only pay the price of deserializing each object once.

please explain what is themes and generic.xaml? [duplicate]

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)?
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 overridden 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 <YourAssembly>.<ThemeName>.dll e.g. PresententationFramework.Aero.dll.
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.

WPF - Managing styles and avoiding messy resource dictionaries

I've spent hours working on an application design in WPF and created a whole bunch of different styles along the way. But I noticed that I actually had just edited the styles in the SimpleStyles.xaml file and not a custom dictionary.
So, I started right clicking all controls I could find and selected "edit a copy" and created a copy in a custom resource dictionary. But then I found that alot of the controls are based on several styles. SimpleScrollViewer e.g contains both the thumb and probably more. This created a huge mess in the overall structure of styles in the entire project.
And thus, my question is as follows;
What should I think about when doing this project from scratch again?
Is it best to edit a copy of the SimpleStyles controls? Is there a tool of some sort to manage stuff like this?
Expression Blend will add a resource dictionary for the Simple Styles the first time you use a SimpleStyled control. For real world projects it is best practice to separate resource dictionaries by resource type and then functional area.
For example you will have horizontal resource dictionaries that fall into the following categories:
Brushes
Control Styles
Converters / Selectors
Since these are horizontal their filenames are pretty self-explanatory (e.g. Brushes.xaml, ControlStyles.xaml, Converters.xaml, etc.)
If you are using Silverlight you should probably think about using Themes. In which case you would create Brushes.xaml and ControlStyles.xaml for each [themeName]\generic.xaml you create.
Then you should create resource dictionaries for functional areas that will house the following things:
Item Templates for various ItemsControls used.
Content Templates for various ContentControls used.
One off Control Styles
Each functional area would have a resource dictionary that had the above items (e.g. CustomerManagementStyles.xaml, Orderingstyles.xaml, etc.)

What is so special about Generic.xaml?

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)?
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 overridden 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 <YourAssembly>.<ThemeName>.dll e.g. PresententationFramework.Aero.dll.
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.

Resources