TopAppBar button AutomationProperties styling in a Windows Store app - c#

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

Related

Bind foreground attribute for child text of textblock element

I've discovered that I cannot set the foreground of text that is contained within a textblock as a child (as opposed to the text being set via the Text attribute on the textblock), by simply using the Foreground attribute on the parent textblock. I've tried setting the attributes TextElement.Foreground and Run.Foreground, but neither work. Does anyone know the preferred method in this case?
Here is my code thus far:
<TextBlock Foreground="{Binding ForegroundColor}">
Sample<LineBreak/>Text
</TextBlock>
edit: Here's an interesting twist: if I take the <LineBreak/> out, the foreground sets just fine
Make sure that you don't have an implicit Run style defined somewhere in your application:
<Style TargetType="Run">
<Setter Property="Foreground" Value="Gray" />
</Style>
This one will override the Foreground setting of the parent TextBlock.
If you do you could add an implicit Run style to the TextBlock:
<TextBlock>
<TextBlock.Resources>
<Style TargetType="Run">
<Setter Property="Foreground" Value="Orange" />
</Style>
</TextBlock.Resources>
Sample<LineBreak/>Text
</TextBlock>

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

How to overwrite a style

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

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>

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