What is the recommended way to skin an entire application in WPF? - c#

I want my WPF application to be skinnable, by applying a certain XAML template, and the changes to be application wide, even for dynamic controls or controls that aren't even in the visual/logical tree.
What can I use to accomplish this type of functionality? Are there any good resources or tutorials that show how this specific task can be done?

The basic approach to take is using resources all through your application and dynamically replacing the resources at runtime.
See http://www.nablasoft.com/alkampfer/index.php/2008/05/22/simple-skinnable-and-theme-management-in-wpf-user-interface/ for the basic approach

The replacing of resource will work but I found "structural skinning" to be more powerfull! Read more about it on CodeProject...
http://www.codeproject.com/KB/WPF/podder1.aspx

I have found the way to apply generic templates to all controls without using template keys. The solution is to use the type of the control as the Style key.
Example:
<Application.Resources>
<Style x:Key="{x:Type Button}" TargetType="{x:Type Button}">
<Setter Property="Button.Background" Value="CornflowerBlue"/>
<Setter Property="Button.Template">
<Setter.Value>
<ControlTemplate x:Name="MyTemplate">
...
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
here the Style key is x:Key="{x:Type Button}", so the style will be applied to all controls of type button without the control declaring the Style property to be a static or dynamic resource.

Related

How to apply style in WPF to all controls without overriding their original styles?

I want to create a style, which will normalize margins for all controls in a specific scenario:
<Style TargetType="FrameworkElement" x:Key="MyStyle">
<Setter Property="Margin" Value="{StaticResource DialogItemsExceptTopMargin}" />
</Style>
I have then a couple of different controls: textboxes, comboboxes, checkboxes etc., to which I want to apply this style.
However, when I do that, their look is immediately reverted to the platform style (I am applying a style from 3rd party library). How can I define my style so that the original styles are kept intact?
Mind: I know, that I can use BasedOn for specific type:
<Style TargetType="TextBox" BasedOn="{StaticResource {x:Type TextBox}}">
...
</Style>
This however would require me to create completely separate styles for all possible controls, which I may use. I tried this trick with FrameworkElement and Control, but I got an error, that there is no such StaticResource.

WPF Override Style Value

I'm using MaterialDesignInXaml for WPF which provides 3rd party controls and styles. I need to edit one of these styles by changing one property.
I am using an Expander control which has a template creating a bunch of child controls. I've discovered the child 'Border' control (4 layers deep) has the property (padding) which I need to set to zero.
See this output from Snoop showing the property I need to change:
Link to image
My question is how can I do this? I've tried extending the style used by the control as follows, but it isn't changing anything so I assume I'm doing something wrong?
<Style TargetType="{x:Type Expander}"
x:Key="MaterialDesignExpanderHeadless"
BasedOn="{StaticResource MaterialDesignExpander}">
<Style.Resources>
<Style TargetType="{x:Type Border}">
<Setter Property="Padding" Value="0"></Setter>
</Style>
</Style.Resources>
</Style>
I am able to use the style like this. And I know this is working for sure:
<Expander Header="Header Content" Style="{StaticResource MaterialDesignExpanderHeadless}">
Some Content
</Expander>
You're right, this method should work. Something else is setting the border's padding.
Snoop is telling you the padding is defined by the parent template, which could be the HeaderSite (ToggleButton).
You could try to extend the ToggleButton style (BasedOn) or redefine it locally.

MenuItem Style seems to be overwritten

It seems that the menuitem style that I am attempting to use gets totally overwritten when I use ItemContainerStyle.
Here's an example of what happens when I use it:
However, when I don't use it, this is what I get:
I much prefer the look of the second menu, but it doesn't support dynamic menu creation due to not using ItemContainerStyle. What could possibly be overwriting the style? I'm using Mahapps Dark base and VS colors/styles.
Base your custom Style on the MetroMenuItem style that comes with MahApps:
<Style TargetType="MenuItem" BasedOn="{StaticResource MetroMenuItem}">
<Setter Property="Background" Value="Yellow" />
</Style>
you should use BaseOn property in the ItemContainerStyle.
<ItemContainerStyle x:Key="MyContainerStyle" BaseOn="{DynamicResource MenuItemStyle}">Style here</ItemContainerStyle>

How to apply a style to all Controls of the same type?

How to apply a style to all Controls of the same type (Buttons for example)?
without specifying the style every time Control declared in XAML.
Ie I want to specify the style once for all the buttons.
Is it possible?
just put it without key
<Style TargetType="{x:Type Button}">
</Style>

how can i use a control in template?

<Style x:Key="abc" TargetType="{x:Type Window}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<button x:name="btn">my button!!</button>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
...
<Window ... Style="{StaticResource styleMainWindow}">
How can i use the button btn?
come up to your expectations,
MessageBox.Show(this.btn1.name);
was occured an error at compile time. and also btn1 didn't show up in intelisense.
Try the FindName method on the ControlTemplate class.
Assuming this is your Control's context:
var button = (Button)this.Template.FindName("btn", this);
I guess mjk6026, you have misunderstood WPF templates from actual member elements of a window.
It is true that when we name a UI element (x:Name) that is not part of any template, we can access that element by name in the code behind.
For templates you would have to use Template type's FindName() method.
So assuming that `this' means the window to which you have applied your style, the way you can access the button is (Button)this.Template.FindName("btn", this)
Let me know if this answers your question...

Categories

Resources