WPF Grouping formattings within a single style - c#

I am working on a WPF application where I by now have a lot of different Resource Dictionaries comprising a huge amount of styles. Many of those styles describe brush settings for borders, backgrounds, etc. Until now, every formatting is in a separate style.
However, what I would like to do (if possible) is to "group" different styles that belong together into a "parent" style - thereby being able to make it a little more manageable which styles concerns which controls.
For example, for a GroupBox, the settings would ideally be registered in a style like this:
<Style x:Key="GroupBoxFormat">
<Style.Resources>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1" x:Key="ElementGradientBrush">
<GradientStop Color="AntiqueWhite" Offset="0" />
<GradientStop Color="Tan" Offset=".7" />
</LinearGradientBrush>
<Border x:Key="BorderFormat" BorderThickness="2">
<Border.Background>
<SolidColorBrush Color="Gold"></SolidColorBrush>
</Border.Background>
<Border.BorderBrush>
<SolidColorBrush Color="Black" ></SolidColorBrush>
</Border.BorderBrush>
</Border>
<FontFamily x:Key="TitleFontFamily">
Arial
</FontFamily>
<FontWeight x:Key="TitleFontWeight">
Bold
</FontWeight>
<!-- Other formats go here... -->
</Style.Resources>
</Style>
As seen in the listing, all separate resources within the style have x:Key attributes specified. As this is seemingly required (as VS complains if it is missing), there must obviously be a reason for that.
From elsewhere in the XAML code, the style can be referenced with {StaticResource GroupBoxFormat}. However, if I want to refer from outside to any of the "inner" properties, say, "BorderFormat" - how do I do that? Something like "dot" notation within C# for accessing object members like SomeObject.SomeMember. Staying in the example, It could be illustrated like "GroupBoxFormat.BorderFormat". I just need the "XAML" way of doing that.

There is nothing like what you're asking for with the "dot notation within C#". The only thing I can suggest is to define global styles in your App.xaml without defining a Key but defining a TargetType:
<Style TargetType="{x:Type TextBox}">
<Setter Property="Margin" Value="3"/>
<Setter Property="MinWidth" Value="110"/>
<Setter Property="IsReadOnly" Value="True"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="TextWrapping" Value="Wrap"/>
</Style>
Now all of your TextBox controls will have these properties defined. If you'd like a specific TextBox to have a different style you must define another TextBox style but set the x:Key attribute as well as the TargetType and then reference the Key.
<TextBox Style{StaticResource YourKey}/>

Related

Override style on parts of ComboBox scrollbar

After lots of research, I stumbled across a relatively simple way to target just specific parts of the control style without using the entire control template. It's partially successful, but I need a little help getting all the way to the end.
Specifically, I am trying to override the Thumb button color of the scrollbar in the dropdown of a ComboBox. The cool technique I came across is the following, which utilizes nested Style.Resources to access the lower objects...
<Style x:Key="MyComboBoxStyle" TargetType="{x:Type ComboBox}">
<Style.Resources>
<Style TargetType="ScrollViewer">
<Style.Resources>
<Style TargetType="ScrollBar">
<Setter Property="Background" Value="LightGreen" />
<Style.Resources>
<Style TargetType="Track">
<Setter Property="Cursor" Value="Cross" />
<Style.Resources>
<Style TargetType="Thumb">
<Setter Property="Background" Value="Red"/>
<Setter Property="Cursor" Value="Hand" />
</Style>
</Style.Resources>
</Style>
<Style TargetType="RepeatButton">
<Setter Property="Background" Value="Red"/>
<Setter Property="Cursor" Value="Hand" />
</Style>
</Style.Resources>
</Style>
</Style.Resources>
</Style>
</Style.Resources>
<!--- rest of ComboBox style definition follows... -->
By sequentially drilling down into the complex control style tree, using nested Style.Resources, I am able to target specific aspects of a control style, without needing the entire style definition.
The xaml code above successfully drills all the way down to the "Track"... I can change things like the margin, cursor, etc. of the Track. But, I just can't seem to get that last step to the Thumb. Also, I can't seem to access the Repeat buttons, which should be at the same level (in the object tree) as the Track.
Looking at the style template for ScrollBars seems to show that the object tree is ScrollBar->Track->Thumb... but I seem to be missing something?
Any ideas on how to get access to the Thumb color?
The default style for the ScrollBar sets the Style property of the Thumb explicitly in the Track:
<Track x:Name="PART_Track" ...>
...
<Track.Thumb>
<Thumb Style="{StaticResource ScrollBarThumbVertical}"/>
</Track.Thumb>
</Track>
This means that your implicit Thumb style won't be applied.
So you will have to define a custom complete ControlTemplate for the ScrollBar to be able to modify the style/template of the Thumb.
Alternatively, you may consider to look it up in the visual tree at runtime and set any of its properties programmatically.

How do I know which systemcolors to use for different controls If I want default classic Window look?

In my DefaultTheme.xaml File I have only set my colors
<SolidColorBrush x:Key="CheckboxForegroundColor" Color="Black"/>
<SolidColorBrush x:Key="CheckboxBackgroundColor" Color="{DynamicResource {x:Static SystemColors.WindowColorKey}}"/>
<SolidColorBrush x:Key="CheckboxBorderbrushColor" Color="{DynamicResource {x:Static SystemColors.WindowColorKey}}"/>
In my ColorTheme.xaml I have done the same but different colors
<SolidColorBrush x:Key="CheckboxForegroundColor" Color="#FFFFFFFF"/>
<SolidColorBrush x:Key="CheckboxBackgroundColor" Color="#FF2d2d30"/>
<SolidColorBrush x:Key="CheckboxBorderbrushColor" Color="#FFCC1517"/>
In my App.xaml
<Setter Property="Foreground" Value="{DynamicResource CheckboxForegroundColor}" />
<Setter Property="Background" Value="{DynamicResource CheckboxBackgroundColor}" />
<Setter Property="BorderBrush" Value="{DynamicResource CheckboxBorderbrushColor}"/>
Changing themes at runtime works fine and my ColorTheme works fine also. But my question is how do I know which systemcolors to use for example Button.Foreground and Button.Background to get the windows Classic look? There are so many Systemcolors I get confused and don't know which one to use for different controls. I have set all my colors to WindowsColorKey in my Default.xaml but seems that it is the wrong way to do it because my application becomes white.
You can make a function to reset the colors of your Checkbox's... Something like:
public void DefaultColors()
{
cbBox1.ForeColor = Color.Beige;
cbBox2.ForeColor = Color.Beige;
//And so on....
}
And run it when you need to. The object's you create in your .XAML are accessible in the affiliated .cs file. Do it there...

how can I design a radio button as a main design and change the main design per button

I have five radio buttons all of them have common style but different color. The styles are all separated. I would like to do a main style and to be able to change the background color for each of them separately.
Define the template in a common base style (e.g. RadioButtonBaseStyle), where you don't hard-code the background color, but use {TemplateBinding Background} instead ; then create several styles based on RadioButtonBaseStyle where you just change the Background property with a setter.
Example:
<Style x:Key="RadioButtonBaseStyle" TargetType="RadioButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RadioButton>
...
<Ellipse Fill="{TemplateBinding Background}" />
...
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="BlueRadioButtonStyle" TargetType="RadioButton" BasedOn="{StaticResource RadioButtonBaseStyle}">
<Setter Property="Background" Value="Blue" />
</Style>
If you need finer control, you could create additional attached properties and use them instead of the standard Background/Foreground/BorderBrush, as explained in this blog post: http://www.thomaslevesque.com/2011/10/01/wpf-creating-parameterized-styles-with-attached-properties/

DatePicker custom template leaves a white box inside

I am trying to make a custom template for datepickers in my program. I am basically using this template line for line (changing colors and things):
http://msdn.microsoft.com/en-us/library/cc278067(v=vs.95).aspx
I have tried going through it and getting rid of this white box (the one INSIDE the datepicker textbox), but it is evading me. Here is a screenshot of what I am seeing:
Do I have to add something extra? Or change some existing values? There is also a MouseOver event that highlights the whitebox with the blue windows gradient, if that helps..
For future people with this problem, I did what Brian suggested, just thought I would post exactly my code, so other people can use it ;) I just added this into app.xaml
<Style x:Key="{x:Type DatePickerTextBox}" TargetType="{x:Type DatePickerTextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DatePickerTextBox}">
<Grid>
<Border x:Name="watermark_decorator" BorderBrush="{DynamicResource cControlColor}" BorderThickness="1"
Background="{DynamicResource cControlColor}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
EDIT: Updating since the clarification points to the white rectangle around the 'Enter text here'.
For this, you need to create a custom template for the DatePickerTextBox which is defined about 2/3rds of the way down that template, and named TextBox. Your best bet will be to use Blend to create a custom template (since it will generate the default template) and then modify the <Border x:Name="watermark_decorator".../> to change the BorderBrush. For example:
<Style x:Key="MyDatePickerTextBoxStyle" TargetType="{x:Type DatePickerTextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DatePickerTextBox}">
<Grid>
<!-- Visual State Manager stuff -->
<Border...>
<!-- other stuff... -->
<Border x:Name="watermark_decorator" BorderBrush="[THE BRUSH YOU WANT]" BorderThickness="1">
<!-- And so on and so forth... -->
</Border>
</Border>
</Grid>
</ControlTemplate>
</Setter>
</Style>
Then, in the DatePicker template, modify the DatePickerTextBox to use this style:
<!-- All DatePicker Template stuff -->
<controlsPrimitives:DatePickerTextBox x:Name="TextBox" Style="{DynamicResource MyDatePickerTextBoxStyle}" ... />
Are you talking about the button with the 15 on it? If so, the look and feel of this part of the DatePicker is defined in the "DropDownButtonTemplate" part of the template. This template includes a large VisualStateManager section, but then defines the template for that button. There are comments that define the beginning and end of the button template:
<!--Start UI-->
... this is the Button Template ...
<!-- End UI-->
For example, if you want to change the color of the Blue rectangle at the top of the button, the MSDN example uses this:
<Rectangle Grid.ColumnSpan="4" Grid.RowSpan="1" StrokeThickness="1">
<Rectangle.Stroke>
<LinearGradientBrush EndPoint="0.48,-1" StartPoint="0.48,1.25">
<GradientStop Color="#FF494949" />
<GradientStop Color="#FF9F9F9F" Offset="1" />
</LinearGradientBrush>
</Rectangle.Stroke>
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.3,-1.1" StartPoint="0.46,1.6">
<GradientStop Color="#FF4084BD" />
<GradientStop Color="#FFAFCFEA" Offset="1" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
And you could change it to a solid color simply by changing it to this:
<Rectangle Grid.ColumnSpan="4" Grid.RowSpan="1" StrokeThickness="1" Stroke="Black" Fill="Green"/>
The "White Box" is actually the Border inside the template with the x:Name="BackgroundGradient", so if you change the Background of that element, you can get rid of the white.

Wpf: Apply custom style of ToolTip at multiple controls

I am working with WPF application. I have created a custom control library where I have customized all controls, meaning added some functionality and restyled them. Same way I have restyled the ToolTip as well. I am using this custom library in other projects. Everything is working fine except ToolTip. ToolTip style is not getting applied. Any Help plz.
Edit:
I have created a custom class named ToolTip that derives from System.Windows.Controls.ToolTip, I have declared style for my custom class as well. Now I want to know how can I get this style applied for ToolTip of each control, I mean I want to create object of my ToolTip whenever user set ToolTip on a control.
in .cs:
public class ToolTip : System.Windows.Controls.ToolTip
{
static ToolTip()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(ToolTip), new FrameworkPropertyMetadata(typeof(ToolTip)));
}
}
in .xaml(Resource Dictionary):
<Style TargetType="{x:Type local:ToolTip}">
<Setter Property="VerticalOffset" Value="-2" />
<Setter Property="HorizontalOffset" Value="20" />
<Setter Property="Height" Value="35"></Setter>
<Setter Property="Placement" Value="Top" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ToolTip}">
<Grid Name="Border" Background="Transparent" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
<Rectangle RadiusX="7.5" RadiusY="7.5">
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0.5,-0.5" EndPoint="0.547,0.913">
<GradientStop Color="#FFEEEEEE" Offset="0"/>
<GradientStop Color="#FFBBBBBB" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<ContentPresenter Margin="10,0,10,0" HorizontalAlignment="Center" VerticalAlignment="Center" TextBlock.Foreground="Black" TextBlock.FontSize="12" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Any Help plz.
Placing the default ToolTip Style in a shared ResourceDictionary in a separate assembly will allow it to be used by multiple projects. You can merge in the MyDefaultStyles ResourceDictionary in the Resources folder of the SharedStyleLibrary.dll into App.xaml using:
<App.Resources>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/SharedStyleLibrary;component/Resources/MyDefaultStyles.xaml"/>
</ResourceDictionary.MergedDictionaries>
</App.Resources>
If MyDefaultStyles contains an implicit ToolTip Style (<Style TargetType="{x:Type ToolTip}">
) it will be used as the default. You can also target it more locally by instead giving the Style an x:Key and then creating an implicit ToolTip Style in whatever scope you want it to apply (i.e. Window, UserControl, single layout Panel):
<Style TargetType="{x:Type ToolTip}" BasedOn="{StaticResource ExternalLibraryNamedStyle}">...
If your custom ToolTip class is only for the sake of applying templates, it's much easier to use an Implicit Style for your ToolTips:
<Style TargetType="{x:Type ToolTip}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<!-- rest of your style here -->
</Style>

Categories