Edit wpf control template but use original styles - c#

Sometimes when I'm editing a copy of the controls original template I don't need to change the original styles and colors, and would like to reference the original ones directly.
For example, I wanted to change the ComboBox template to add some filtering buttons in the drop down, its toggle button refers to a Style that is also copied into the file. I would like to refer to the original style so my XAML isn't overly cluttered.
Edit:
So here is part of the XAML code that is created when you choose to edit a copy.
The ControlTemplate is what I want to change, but I don't need the ComboBoxToggleButton Style, and so for the toggleButton I'd like to set its style to the one the ComboBoxToggleButton Style was copied from. Is there some namespace that they are all stored in, or are they inaccessible?
<Style x:Key="ComboBoxToggleButton" TargetType="{x:Type ToggleButton}">
...
</Style>
<ControlTemplate x:Key="ComboBoxTemplate" TargetType="{x:Type ComboBox}">
<Grid x:Name="templateRoot" SnapsToDevicePixels="true">
...
<ToggleButton x:Name="toggleButton" ... Style="{StaticResource ResourceKey=ComboBoxToggleButton}"/>
</Grid>
</ControlTemplate>
And approximately what I'd like it to be like
<Window xmlns:baseStyles="{namespace/url to the default wpf styles}">
<ControlTemplate x:Key="ComboBoxTemplate" TargetType="{x:Type ComboBox}">
<Grid x:Name="templateRoot" SnapsToDevicePixels="true">
...
<ToggleButton x:Name="toggleButton" ... Style="{StaticResource ResourceKey=baseStyles:ComboBoxToggleButton}"/>
</Grid>
<ControlTemplate.Triggers>
...
</ControlTemplate.Triggers>
</ControlTemplate>

Right, so Combobox isn't your basic bare templated control. Within it's ControlTemplate is a unique ToggleButton (hence the additional instance-specific Style template for it) which it requires. Once you introduce a new ControlTemplate than that's now all it knows. It CAN NOT reference a Style template inside of the original ControlTemplate since it's not a resource available outside of it. Style and ControlTemplate are different beasts.
You have two options. Either you take that unique ToggleButton Style Template and put it somewhere it can be reached as a StaticResource and ref it on the ToggleButton instance inside your ControlTemplate via the normal <ToggleButton Style="{StaticResource ComboBoxUniqueToggleButtonStyleKeyNameYouGiveIt}" ..../>
(Like if it were in a resource dictionary, except then it's loaded all the time which generally isn't necessary).
Or, you can embed it directly in your ControlTemplate just like they do in the default style/controltemplate for ComboBox.
You can inherit parts of a Style template via BasedOn but you can only have one ControlTemplate at a time.
Hope this helps, and I'll retract my duplicate vote.

To reuse the default WPF style to ComboBox, use:
<Style TargetType="ComboBox">
<!-- Setters in need of change -->
</ Style>
If you want to inherit from a Style you created yourself, you can use:
<Style TargetType="ComboBox" BasedOn="{StaticResource YourExistentStyle}">
<!-- Setters that need to change -->
</ Style>

Related

How to globally change the styling of the dottet lines around all focusble elements in one place?

From here I learned how to change the styling of dotted lines around focused button. I would like to apply the same thing on all focus-able elements of the current WPF application (or if not possible current page) in one place ( not doing separately for focus-able buttons, textboxes etc)
PS. Preferably in code behind
Define this Style in your App.Xaml .
<Application.Resources>
<Style x:Key="StyleFocusDefault" TargetType="{x:Type Control}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Control}">
<Grid>
<Rectangle StrokeThickness="2" Stroke="Black" StrokeDashArray="2"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
And then you can apply like : < ... FocusVisualStyle="{DynamicResource StyleFocusDefault}" .../>
This will change FocusVisualStyle for all Controls who have FocusVisualStyle property. You can further experiment with this appaorach for various controls.

Creating style resource for custom control removes template

I've got a custom control in WPF, which has a variety of dependency properties that allow visual customization. For the sake of brevity I won't post the entire control, but it basically is setup like this:
<UserControl.Resources>
<Style TargetType="{x:Type MyControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MyControl}">
<Border BorderBrush="{TemplateBinding BorderColor}">
// more stuff here
<ContentPresenter/>
</Border>
</ControlTemplate>
</Setter>
</Setter>
</Style>
</UserControl.Resources>
The BorderColor property works fine if I set it directly, like this:
<ctl:MyControl BorderColor="Brushes.Red">....</ctl:MyControl>
But I want to set it application-wide. The problem I have is if I simply set the style with no key, it does not apply. Like this:
<Window.Resources>
<Style TargetType="{x:Type ctl:MyControl}">
<Setter Property="BorderColor" Value="Brushes.Red"/>
</Style>
</Window.Resources>
This does not do anything to the control. So I thought I'd just set a key and apply that style, like this:
<Style TargetType="{x:type ctl:MyControl}" x:Key="myStyle">....</Style>
<ctl:MyControl Style="{StaticResource myStyle}">.....</ctl:MyControl>
But this causes the control to vanish, I'm assuming because it's removing the Template. What am I doing wrong? With other framework controls you can just set the properties you want without losing the control template.
You need to inherit from the default style you have created.
inherit style from default style

WPF ControlTemplate AND DataTemplate

I have ListView where I would like to apply a custom ControlTemplate to it's items. It is defined like this:
<ListView ItemsSource="{Binding MyAwesomeItems}" ...
MyAwesomeItems holds different classes. So I thought to myself: "Well, hello DataTemplates."
To make the contained items look the way I want them to, I have defined a ControlTemplate like this:
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<Border><ContentControl Content="{TemplateBinding Content}"/></Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
I have used ContentControl with Binding to TemplateBinding Content. I expected that WPF would then insert my items inside that ContentControl, using whatever DataTemplate I have defined for it.
But instead, it looks like WPF just uses the items .ToString() and does not apply any DataTemplates. Is this intended behaviour?
What I want to achieve is: Have a list of items, where the container of each item looks exactly the way I want and the content of that container comes from the DataTemplate.
In a ControlTemplate for a ContentControl you usually use an empty ContentPresenter tag. In your case:
<ControlTemplate TargetType="ListViewItem">
<Border>
<ContentPresenter/>
</Border>
</ControlTemplate>
The ContentPresenter has a ContentSource property which defaults to "Content" and sets all the necessary properties (Content, ContentTemplate, etc.).
See here for details.

Override style for RadioButton if it is placed in a Menu

is there any way to override the default style of the radiobuttons, if it is placed in a menu?
but if it is in the window, it should look like ever. but i will not use x:key. it should found this automatically.
I see two solutions:
Create style with x:Key but place it in Menu.Resources - that way it will be only applied to menu items.
ItemsControls (Menu is one) have property called ItemContainerStyleSelector. You can create Your own StyleSelector and set style depending on container type.
it is very easy, if you know how :)
<style TargetType="{x:Type Menu}">
<Setter Property="Template>
<Setter.Value>
<ControlTemplate TargetType="{x:Type Menu}">
<ControlTemplate.Resources>
<Style Targettype="{x:Type Radiobutton}>
</Style>
</ControlTemplate>
<StackPanel IsItemsHost="True" Width="{TemplateBinding Width}" Height= {TemplateBinding Height} />
</Setter.Value>
</Setter>
</style>
you have to control the writing of the keywords, because i write it so and not on Visual Studio.
override the menu standard with a stackpanel, because i had found no other way to set the Resources.
It is easy, but without the answer from Varius, i didn't found this.
You have to do the same for MenuItem.
I post this, because i think, it maybe would help other peoples with the same problem.
i had searched long time and find nothing.

Issue with applying style on WPF UserControl

I have a user-control and I want to use it in some other project. There is no problem when I set some value to its properties directly:
<local:MyUserControl prop1="val1" prop2="val2">
...
</local:MyUserControl>
But I can't apply a style to it. I tried:
<Window ...>
<Window.Resources>
<Style x:Key="MyUserControlStyle" TargetType="{x:Type local:MyUserControl}">
<Setter Property="prop1" Value="val1"/>
<Setter Property="prop2" Value="val2"/>
</Style>
</Window.Resources>
<Grid>
<local:MyUserControl Style="{StaticResource ResourceKey=MyUserControlStyle}">
...
</local:MyUserControl>
</Grid>
</Window>
Where did I wrong? -Thanks
Using dear #Mario Vernari's instructions, I found it out that the problem was due to a bad strategy which I'd used to create my UserControl. I wanted to create a UserControl that be able to hold some other ones. So I had tried this:
<UserControl x:Class="MyNamespace.MyUserControl"
...
Style="{DynamicResource ResourceKey=MyUserControlStyle}">
<UserControl.Resources>
...
<Style x:Key="MyUserControlStyle" TargetType="{x:Type UserControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type UserControl}">
<Border BorderBrush="{Binding Path=DP1}">
...
<ContentPresenter ... Content="{TemplateBinding Content}"/>
...
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
</UserControl>
Where DP1 is a dependency property of type Brush. The UserControl which has been created through this way works if you set its properties (like DP1) directly. Absolutely this is not the true way as #Mario told me:
...When you use an UserControl, it means that you already know its layout, and there is no need to style the control further. You are defining its style twice at the same time thus results a collision...
And he added:
Instead, you should use a CustomControl; Define the default style in the Themes folder (if you own regular Visual Studio, it makes automatically). Afterward, you may override the default style in your own app. In the same way you would do for a normal base class and its derived.
Follow this:
http://www.codeproject.com/KB/WPF/WPFCustomControl.aspx ...
Obviously, in this case we need to derive our lookless control from ContentControl class (instead of Control class). You may take a look at this & this to master the details.
Here, I give thanks to #Mario again. ;)
You are giving Style="{StaticResource ResourceKey=MyUserControlStyle}".
It's just - Style="{StaticResource MyUserControlStyle}".

Categories

Resources