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>
Related
I have a Hyperlink with various bindings that I have put into a DataTemplate to ensure the code isn't repeated. To use this I specify a ContentControl with a ContentTemplate. However, using a ContentControl inline with TextBlock text causes the link to be offset. I've got down to the following test case where this occurs:
<TextBlock>Text with a <ContentControl>Inline content control</ContentControl> in it.</TextBlock>
The only way I've found to get around this is to specify a negative margin on the ContentControl, but obviously this is not ideal as it will not work when the font size changes.
I don't think it's possible to get a ContentControl to behave the same as an inline element, and the only way to get a ContentControl to stay inline with the text would be to modify padding/baseline etc. which can't respond to DPI changes and is obviously a bit of a hack.
I used Grx70's suggestion and instead moved my bindings into a style which I then set on the Hyperlink as needed:
<Style x:Key="CustomHyperlink" TargetType="{x:Type Hyperlink}" BasedOn="{StaticResource {x:Type Hyperlink}}">
<Setter Property="NavigateUri" Value="{Binding TheUri}"/>
<Setter Property="Command" Value="{Binding TheCommand}"/>
<Setter Property="CommandParameter" Value="{Binding NavigateUri, RelativeSource={RelativeSource Self}}"/>
</Style>
<TextBlock TextWrapping="Wrap">
...please <Hyperlink Style="{StaticResource CaseHyperlink}">view in browser</Hyperlink> and...
</TextBlock>
I've got a ComboBox I'm hiding and showing with a Style.Setter on the Visibility property:
<ComboBox ItemsSource="{Binding ElementName=BVTWindow, Path=DataContext.AreaList}" SelectedItem="{Binding Path=Area}">
<ComboBox.Style>
<Style TargetType="{x:Type ComboBox}">
<Style.Setters>
<Setter Property="Visibility" Value="Collapsed" />
</Style.Setters>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=BVTWindow, Path=DataContext.IdentitySelection}" Value="Test Management">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</ComboBox.Style>
</ComboBox>
This works great. Unfortunately, applying the style setter (for some reason) removes the color theme from the ComboBox. Now it's a light grey box with white text and nearly unreadable.
I tried adding Foreground and Background attributes to the ComboBox tag, but it had no effect.
I also tried adding Setter Properties for Foreground and Background to the DataTrigger, also with no effect.
I need to either stop the theme from being removed from the box, manually set the text color, or manually set the background color.
I read one article saying that Windows 8 (which is what I'm using) interferes with ComboBox styling, but there wasn't an easily-understandable solution for it.
Any advice would help me out a lot. Thanks in advance.
This articles explains it pretty well:
http://social.technet.microsoft.com/wiki/contents/articles/24240.changing-the-background-color-of-a-combobox-in-wpf-on-windows-8.aspx
Basically, Windows 8 has a different setup for ComboBox, and it breaks some of the style attributes. You can still style it, but you've got to right click the ComboBox and pick "edit template". This will generate a massive amount of xaml in your project view (color schemes for every possible combination of states), but you probably don't need all of it. I played with commenting / uncommenting sections to figure out what each Trigger and Setter affected, then set my colors and killed the extra parts.
I have a new solution that's much cleaner, faster, easier and better-looking than my previous idea:
Just wrap the ComboBox in a WrapPanel or StackPanel and apply the Style Setter to the parent. The control will retain it's proper style and the parent panel should be transparent anyway, so styles won't matter there. Worst case, you've got a WrapPanel with only one item in it and two extra lines of code in the xaml. This will work with other controls as well, as I just had to do it with a Checkbox.
Here's an example:
<WrapPanel>
<WrapPanel.Style>
<Style TargetType="{x:Type WrapPanel}">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding DataContext.TesterIdentitySelection.CanEdit, ElementName=BVTWindow}" Value="true">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</WrapPanel.Style>
<ComboBox ItemsSource="{Binding Path=DataContext.AreaList, ElementName=BVTWindow}" DisplayMemberPath="Name" SelectedItem="{Binding Path=Area, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" ToolTip="Select the testing area."/>
</WrapPanel>
The combo box is inside the wrap panel, and the wrap panel is what has the show/hide behavior applied to it. Since the wrap panel doesn't really have any style itself (just an invisible holder), everything ends up looking great.
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>
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
Is there a simple way to just get TextTrimming to work with a ContentPresenter?
I have implict styles for TextBlock and AccessText that have TextTrimming set to CharacterEllipsis, but it's not picked up by the ContentPresenter. I can change the ContentPresenter to an AccessText or TextBlock and set it there, but then the template only handles text content.
Any suggestions?
Thanks!
Implicit Styles for elements that derive from UIElement, but not Control, are not applied if the element is defined in a control's Template unless the implict Style is defined in the application Resources. The same holds true for TextBlocks used by ContentPresenter.
For example, in the following XAML the TextBlock that is ultimately used to present the button's content will not get the implicit Style:
<Window.Resources>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="Red" />
</Style>
</Window.Resources>
<StackPanel>
<Button Content="Will not be red" />
<TextBlock Text="Will be red" />
</StackPanel>
If you take that exact same Style and move it to the application's Resources, then both will be red:
<Application.Resources>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="Red" />
</Style>
</Application.Resources>
So you can either move your implicit Style to application resources, which is generally not a good idea. Or you can customize the display for the specific scenario you have. This can include adding an implicit DataTemplate, or customizing a control's Template.
If you can provide more information, then it would be easier to know which is the best approach.
Thanks to this Gist by James Nugent: "WPF style which puts character ellipsis on button contents without replacing the ContentPresenter with a TextBlock and thus losing the ability to support access keys."
This worked for me:
<ContentPresenter.Resources>
<Style TargetType="TextBlock">
<Setter Property="TextTrimming" Value="CharacterEllipsis"></Setter>
</Style>
</ContentPresenter.Resources>