How to overwrite a style - c#

I use the DecimalUpDown control from the Extended WPF Toolkit in my WPF ModernUI app:
<xctk:DecimalUpDown Value="{Binding myProperty}" Increment="1" Maximum="10" Minimum="0" />
What bugs me is this: If an accent color is selected, for example red, then standard ModernUI-Controls such as textboxes adapt that color nicely:
The DecimalUpDown control however sticks to its style. For example, the control is blue when it is active and the RepeatButtons used in the control do not look like ModernUI buttons:
Even worse: all TextBoxes in the View where the DecimalUpDown control is placed now exhibit this style and are highlighted in blue instead of red:
How can I change that?
EDIT: this is the generated ControlTemplate when I follow Ben's good advice:
<ControlTemplate x:Key="ControlControlTemplate1" TargetType="{x:Type Control}">
<xctk:ButtonSpinner x:Name="PART_Spinner" AllowSpin="{Binding AllowSpin, RelativeSource={RelativeSource TemplatedParent}}"
...>
<xctk:WatermarkTextBox x:Name="PART_TextBox" AutoMoveFocus="{Binding AutoMoveFocus, RelativeSource={RelativeSource TemplatedParent}}"
AutoSelectBehavior="{Binding AutoSelectBehavior, RelativeSource={RelativeSource TemplatedParent}}"
AcceptsReturn="False"
.../>
</xctk:ButtonSpinner>
<ControlTemplate.Triggers>
...
</ControlTemplate.Triggers>
</ControlTemplate>
It's then possible to style the WatermarkTextBox and the ButtonSpinner:
What I have not managed so far: Is there a way to access the RepeatButtons inside the ButtonSpinner, so that I can set their styles as well?

It´s probably necessary to write your own template and define the color there. Sometimes there is no direct way to change properties which are part of the UI-element.
Try to edit a copy of the template and search for the blue color value.
Right click the DecimalUpDown and go to edit template
If the color value is no set there, it´s possible it´s set via the System.Colors (e.g. ActiveBorderBrush)
<SolidColorBrush x:Key="{x:Static SystemColors.ActiveBorderBrush}" Color="Orange" />
The System.Colors define some standard behavious when a control is active, highlighted, etc. MSDN lists all existing ones:
https://msdn.microsoft.com/en-us/library/system.windows.systemcolors%28v=vs.110%29.aspx

Related

WPF, Telerik: Change control style when disabled

I have a trouble with Telerik control.
<Style x:Key="RadDropDownButtonStyle" TargetType="telerik:RadDropDownButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="telerik:RadDropDownButton">
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="Red" />...
So, this handles Disabled property. Text changes its color, but it is not contrast, something like watermark.
How can I disable this? And make disabled control more contrast?
Text changes its color, but it is not contrast, something like watermark.
For future references, this is caused by the Opacity property. When the opacity is lower than 1 it becomes lighter.
The problem you are describing is something very familiar. And I'm afraid there isn't any great way to get rid of this, so much so that the best advise that I can give you is to not even bother. If anything, it will just make using the themes and styles a real pain.
However there is an easy way to get your desired behaviour by replacing the IsEnabled="False" property with IsHitTestVisible="False" and Focusable="False"
These will make it impossible to click or focus the control by keyboard navigation, basically making it disabled. Now you can add some more style properties to make it look the way you believe a disabled control should look like. By for example setting the wanted Foreground and Background or you could even use an Opacity closer to 1 (ex: 0.9) which will make it less dark than the original but still dark enough to read properly.
I hope this helps you with your current problem, just leave a comment if you want me to clarify further.
EDIT 1: Apperently can overwrite the opacity change by using your own DataTemplate for the control. How to have 100% opacity even when control is disabled in wpf C#
EDIT 2: I'll give you an example of how to use the other properties correctly.
This is how you would define a disabled button normally, and doing so will make the text lighter and less readable.
<!-- Simple disabled button -->
<telerik:RadButton Content="Test Button 1" IsEnabled="False" />
<!-- Button with binding on IsEnabled -->
<telerik:RadButton Content="Test Button 2" IsEnabled="{Binding MyBinding}" />
Now I'll show you how you can mimic these results by using the properties IsHitTestVisible and Focusable.
<!-- Simple disabled button -->
<telerik:RadButton Content="Test Button 1" IsHitTestVisible="False" Focusable="False" />
<!-- Button with binding on IsEnabled -->
<telerik:RadButton Content="Test Button 2" IsHitTestVisible="{Binding MyBinding}" Focusable="{Binding MyBinding}" />
In the above examples, the buttons will look as if they are still enabled. However you won't be able to focus or click them. Of course we do want to see some difference to be able to tell that they can't be used.
<!-- Styled disabled button -->
<telerik:RadButton Content="Test Button 1" IsHitTestVisible="False" Focusable="False" >
<telerik:RadButton.Style>
<Style TargetType="telerik:RadButton">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=Self}, Path=IsHitTestVisible}" Value="False">
<Setter Property="Opacity" Value="0.8"/>
</DataTrigger>
</Style.Triggers>
</Style>
</telerik:RadButton.Style>
</telerik:RadButton>

How do you style a single TextBox among others?

I have a WPF textbox among others that I would like to create a style for.
This style should only apply to this type of textbox.
Here is my textbox:
<TextBox Text="{Binding DeviceInformation.SerialNumber, Mode=OneWay}" BorderThickness="0" Background="Transparent" IsReadOnly="True"/>
My text box basically simulates a label I can copy.
How do I make this into a style and target only this textbox?
If you set Key property on your Style definition, then it will be applied only on TextBoxes that have set this Style. Style={StaticResource=ExampleKey}
Example:
<Window.Resources>
<Style TargetType="TextBox" x:Key="ExampleStyle">
<Setter Property="BorderThickness" Value="0"></Setter>
</Style>
</Window.Resources>
You can also have application-wide styles defined in App.xaml

Cannot override controls foreground colour in wpf

Hi all this is a problem that has been driving me crazy for a few days now.
Put simply whenever i declare a foreground colour on anything that derives from a TextBlock control that foreground colour is recognised at design time but at run time it always defaults to being black.
Its as if the foreground property is being ignored on the control.
So for example normally i would expect the following to render a button with white text:
<Button x:Name="MyButton" Content="Hello World" Foreground="White" ... />
However this renders a button and the foreground text colour is black. Its effectively ignoring the Foreground setter property.
The only way to get this to work as expected is to the do following:
<Button x:Name="MyButton" .... >
<TextBlock Text="Hello World" Foreground="White"/>
</Button>
This way works and the button renders correctly with white text. But i know i shouldnt have to explicitly define the buttons textblock like this.
The same behaviour occurs with anything that derives from textblock.
Does anyone have any idea why this is happening ?
UPDATE:
I have checked my solution for styles that are applied to TextBox. I have defined my own style on the TextBlock which is:
<Style x:Key="TextBlockText" TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="#FF63798F"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="VerticalAlignment" Value="Bottom"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
</Style>
Which as you can see defines a value for the foreground. However when i remove this style from my resource dictionary the above problem still remains.
Additional information is that I am using the MahApps.Metro libraries and Im wondering if this is causing the issue.
Does anyone have any other ideas ? Or even thoughts of where to investigate ??
Every control in WPF has a Template associated with it. I think somehow a style defined on your button which does not count the foreground property.
For instance,
<Style x:Key="DialogButtonStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Ellipse Fill="{TemplateBinding Background}"
Stroke="{TemplateBinding BorderBrush}"/>
<TextBlock Foreground="{TemplateBinding Foreground}">
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"/></TextBlock>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Can you use Style={StaticResource DialogButtonStyle} and define foreground for the Button. See here we used TemplateBinding on Foreground of the TextBlock rather than defining the color inside it.
I'd recommend keeping your TextBlock style as it is, and in your Button or other controls, at the Template level, add a new Resource with a TextBlock style. It will be in that template's domain so it won't affect the other textblocks but will override the style of the main TextBlock.
For example:
<ControlTemplate>
<Grid>
<Grid.Resources>
<!-- Put a new/duplicate TextBlock Style here with
the appropriate Foreground color, or TemplateBinding
and it will override it for this Grid's children -->
</Grid.Resources>
<TextBlock />
</Grid>
</ControlTemplate>

TopAppBar button AutomationProperties styling in a Windows Store app

Is it possible to style the AutomationProperties.Name value with a different color?
I get the basic text color from the dark theme in my app. I have a custom background color and thats why I need a specific ForegroundColor and TextColor for this attribute (Value="OtherUserAppBarButton")
<Style x:Key="LogoutAppBarButtonStyle" TargetType="ButtonBase"
BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="OtherUserAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="Other User"/>
<Setter Property="Content" Value=""/>
<Setter Property="Foreground" Value="#ffffffff" />
</Style>
Has somebody an idea?
To achieve that you will need to modify AppBarButtonStyle which you are basing your button style on. You can find it in Common\StandardStyles.xaml inside your project. You can either modify the style in this file directly or create a copy of it inside App.xaml if you need the unmodified style as well.
You need to change the following block inside the style's ControlTemplate:
<TextBlock
x:Name="TextLabel"
Text="{TemplateBinding AutomationProperties.Name}"
Foreground="{StaticResource AppBarItemForegroundThemeBrush}"
Margin="0,0,2,0"
FontSize="12"
TextAlignment="Center"
Width="88"
MaxHeight="32"
TextTrimming="WordEllipsis"
Style="{StaticResource BasicTextStyle}"/>
As you can see the Foreground property is fixed to AppBarItemForegroundThemeBrush. You can change it to {TemplateBinding Foreground} for it to match the color you set in LogoutAppBarButtonStyle or you can give it another custom fixed color directly in the template.
Also don't forget about the styles for other visual states (PointerOver, Pressed, Disabled and Checked). They are also set to theme colors. You can change them inside the VisualStateManager for the template

How do I bind template with style?

I have a C# WPF application where I need to create a bunch of image/text buttons with different colors. To that end I created an ImageButton derived from Button class.
I want my button to have round corners so I have created the following control template:
<ControlTemplate x:Key="RoundedButtonTemplate" TargetType="{x:Type MyProject:ImageButton}">
<Grid>
<Border x:Name="border" Background="WHAT DO I PUT HERE?" CornerRadius="10"/>
</Grid>
</ControlTemplate>
Now I want to be easily able to change the color of the border above, just by changing styles in XAML. I have the following styles defined.
Green Button Style:
<Style x:Key="GreenButtonStyle" TargetType="{x:Type MyProject:ImageButton}">
<Setter Property="Background" Value="{DynamicResource GreenButtonBrush}"/>
RoundedButtonTemplate}"/>
</Style>
Blue Button Style:
<Style x:Key="GreenButtonStyle" TargetType="{x:Type MyProject:ImageButton}">
<Setter Property="Background" Value="{DynamicResource BlueButtonBrush}"/>
RoundedButtonTemplate}"/>
</Style>
My client code looks like this:
<local:ImageButton HorizontalAlignment="Left" Margin="24,19.234,0,20" Width="97" Grid.Row="3" Style="{DynamicResource GreenButtonStyle}" Template="{DynamicResource RoundedButtonTemplate}"/>
My question is how do I make the template know which style to use? I tried adding the following property to my style, but didn't have much success:
<Setter Property="Template" Value="{DynamicResource RoundedButtonTemplate}"/>
I'm guessing that ImageButton inherits from UserControl since this is a composite control. If not, you probably should. MSDN discusses inheriting from Control vs UserControl. I would put the Border in there, and inside a Button and a TextBlock or something.
One way to do this would be to define a Dependency Property on your new ImageButton class, something like "BorderBackground." You link this up to change the Border's Background color when you set it. I can provide sample code if you like.
When you set your styles, the target property would be "BorderBackground." This would eliminate the needs for any change to the ControlTemplate, which I generally try to avoid.
Does this help at all?
Or answer your original question, I am not sure if the Template would know how to have the style applied since your style targets the Background of the ImageButton control, not the Background of the Border control.
I think I figured it out. All that was needed was placing the following text in my template definition:
Background="{TemplateBinding Background}"
More information can be found in this article:
TemplateBinding: a bridge between styles and templates

Categories