WPF Apply default style to custom control - wpf

I have created a custom combo box control which inherits from Combobox class. There is a type style defined for ComboxBox type on ResourceDictionary which applied automatically for all combo boxes but this is not getting applied the custom control.
Style defined on App.xaml
<Application.Resources>
<Style x:Key="{x:Type ComboBox}" TargetType="{x:Type ComboBox}">
<Setter Property="Background" Value="Gray"/>
</Style>
</Application.Resources>
Custom ComboBox
public class AutoComboBox : ComboBox
MainWindow.xaml
<StackPanel Orientation="Vertical">
<ComboBox Width="200"/>
<local:AutoComboBox Width="200"/>
</StackPanel>
The first combo box will have Background as Gray color as the style defined on App.xaml is applied. But the second combo box still show the default background color.
Is there any way we can apply the same type style on custom control without creating duplicate style for custom control?

Are you using a Theme approach?
If so you should have a ../Themes/Generic.xaml which is your ResourceDictionary.
Your ResourceDictionary should have a <Style> in it with the TargetType="{x:Type local:YourControl}" set for your style.
Furthermore, you should check that in your AssemblyInfo.cs file that ResourceDictionaryLocation.SourceAssembly is set for each of your themes.

Related

Default DataGridComboBoxColumn ControlTemplate

Without bothering you with what I intend to do, could someone kindly point out where I can get the default DataGridComboBoxColumn ControlTemplate. I am sure there must be a Control Template or some kind of style that targets a DataGridComboBoxColumn, otherwise how did Microsoft build the DataGridComboBoxColumn.
Without bothering you with what I intend to do
I think it is not so unimportant, because of these advises on MSDN page DataGridComboBoxColumn Class:
Represents a DataGrid column that hosts ComboBox controls in its
cells.
and
If you want to use other controls in your DataGrid, you can create
your own column types by using DataGridTemplateColumn.
For styling (also ControlTemplate!) of ComboBox you can use ElementStyle and EditingElementStyle properties of DataGridComboBoxColumn.
Default template for ComboBox you can find here: ComboBox Styles and Templates
Small example:
<DataGridComboBoxColumn.ElementStyle>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBox">
<TextBlock Text={Binding SomePropertyOfYourRowDataContext}/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DataGridComboBoxColumn.ElementStyle>
Could someone kindly point out where I can get the default DataGridComboBoxColumn ControlTemplate.
A DataGridComboBoxColumn is not a Control and hence it has no ControlTemplate.
It creates a ComboBox in its GenerateEditingElement method and it is this ComboBox that you see when the cell of a DataGridComboBoxColumn is in edit mode: https://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/Controls/DataGridComboBoxColumn.cs,90924e66a85fbfa4.

WPF - style hyperlinks in DataGrids

I need to style hyperlinks in WPF4 DataGrid control (they appear in columns of type DataGridHyperlinkColumn). I have many DataGrids in the project and would like to apply the hyperlink style to all of them.
I found this Q&A: WPF Style DataGridHyperlinkColumn and created the style for HyperLink control:
<Style TargetType="{x:Type Hyperlink}">
<Setter Property="TextDecorations" Value="" />
</Style>
It works fine, but obviously it also affects all other hyperlinks, eg. in
<TextBlock>
<Hyperlink NavigateUri="http://www.google.co.in">Click here</Hyperlink>
</TextBlock>
How can I target only hyperlinks in DataGrids? In CSS syntax it would be something like
DataGrid Hyperlink {TextDecorations: ""; }
Due to property value inheritance all instances of links inherits the style that you have created because you did not use x:key attribute.
You can add x:Key attribute:
<Style TargetType="{x:Type Hyperlink}" x:Key="HyperlinkStyle1">
<Setter Property="TextDecorations" Value="" />
</Style>
by using this you can reference this from your controls like below:
<Hyperlink NavigateUri="http://www.google.co.in" Style={StaticResource HyperlinkStyle1}>Click here</Hyperlink>

TabControl Styles

I am learning to use styles in wpf and I am creating a style for a Tab Control. I was wandering if someone can please tell how I can stop a style propagating down, for example I have a Tab control that where one of the tabitems holds another tabcontrol, of closable tabitems, (yes Nested TabControl O.o).
So in my first UserControl it holds the "Master" TabControl this UserControl also has a UserControl.Rescource that has a style for this TabControl. This style propogates down to the nested tabcontrol, how can I stop this from happening?
The other tab control is kept in a seperate usercontrol class.
Looks Something like this:
<UserControl.Resources>
<Style TargetType="{x:Type TabControl}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="Template">
...
<!-- The Style -->
...
</UserControl.Resources>
<TabControl SelectedIndex="{Binding Path=TabIndexFocus}">
<TabItem Header="Tab1" IsEnabled="{Binding Path=IsEnabled_WorkSpace}" >
<View:NestedTabControl/>
</TabItem>
<TabItem Header="Tab2">
<View:SomeOtherView />
</TabItem>
.....
</TabControl>
Thanks All :D
Make a copy of the entire default Style Template, then I would recommend putting it in a separate resource dictionary but either way you will give the style template a unique x:Key name so like;
<Style x:Key="NonDefaultTabControlStyle" Target="{x:Type TabControl}">
Then in your tab control itself call your specific Style template like;
<TabControl Style="{StaticResource NonDefaultTabControlStyle}" ....>
When you specify the uniquely named Style template it will use it, when you don't it will use the default. Hope this helps and best of luck!

Why does TextBox get a padding when Grid.Margin is set in App.xaml?

A simple window:
<Window x:Class="MyApp.MainWindow" xmlns="..." xmlns:x="...">
<Window.Resources>
<Style TargetType="Grid">
<Setter Property="Margin" Value="8"/>
</Style>
</Window.Resources>
<Grid>
<TextBox VerticalAlignment="Top" HorizontalAlignment="Left">Test</TextBox>
</Grid>
</Window>
It looks like this:
Now we remove Window.Resources:
<Window x:Class="MyApp.MainWindow" xmlns="..." xmlns:x="...">
<Grid>
<TextBox VerticalAlignment="Top" HorizontalAlignment="Left">Test</TextBox>
</Grid>
</Window>
And add the style definition to App.xaml:
<Application x:Class="MyApp.App" xmlns="..." xmlns:x="..." StartupUri="View\MainWindow.xaml">
<Application.Resources>
<Style TargetType="Grid">
<Setter Property="Margin" Value="8"/>
</Style>
</Application.Resources>
</Application>
Strangely, the TextBox now gets a padding:
Why?
Implicit Styles for elements that do not derive from Control (i.e. Grid) will be applied to all instances of that control when placed in the Application resources. But they will not be applied to certain instances when the Style is placed any where else.
Effectively, elements inside ControlTemplate are except from implicit Styles for their type, unless that Style is defined in application resources.
Since Grid is not a control (i.e. it doesn't derive from Control), placing it's Style in the application resources will affect every Grid in your application. This includes Grids defined in the ControlTemplate of controls, like TextBox.
More information can be found here.
I suppose the default content of textbox contains a grid while placing the inner content. When in application resources, the TextBox styling occurs, the Grid Style also gets applied to the Grid inside the TextBox.
But when the same Grid style is applied in window resources (i.e after global styling occurs), it does not affect the Grid inside the TextBox.

Derived classes and theme inheritance in WPF?

I'm building a WPF application, and I derived a bunch of controls from the standard WPF control types -- textblocks, buttons, etc. I tried adding a resource dictionary to app.xaml to set the theme, but my custom controls don't seem to be respecting it. (For example, standard Buttons take the Aero theme just fine, but a myButton derived from a Button is still lookless.) Is there a way I can set the theme for my derived controls to be the same as for the base controls?
EDIT: I should note that these custom controls are instantiated at runtime, so I can't manipulate their properties directly via XAML. I can change particular properties like background color by using a Setter in the application resource dictionary, but haven't found a way to set a theme using that technique.
If you have this style in a Resource Dictionary called Dictionary1.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="MyButtonStyle"
TargetType="{x:Type Button}"
BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Width" Value="75" />
<Setter Property="Height" Value="23" />
</Style>
</ResourceDictionary>
Then you can set it on any button with this code behind
Uri resourceLocater = new Uri("/YourAssemblyName;component/Dictionary1.xaml", System.UriKind.Relative);
ResourceDictionary resourceDictionary = (ResourceDictionary)Application.LoadComponent(resourceLocater);
Style myButtonStyle = resourceDictionary["MyButtonStyle"] as Style;
Button button = new Button();
button.Style = myButtonStyle;

Resources