Foreground does not apply for labels - wpf

I have some labels like this:
<Label x:Name="ledCalculate" Width="Auto" Content="Calculate" Height="25" FontFamily="Cambria" FontSize="18.667" VerticalContentAlignment="Bottom" Padding="10,0,0,0" BorderThickness="0,0,0,1" Style="{StaticResource RightPanelLabels}" Grid.Row="11"/>
I defined a style for it:
<Style TargetType="Label" x:Key="RightPanelLabels" BasedOn="{StaticResource
{x:Type Label } }">
<Setter Property="Foreground" Value="#FFEABEBE"></Setter>
<Setter Property="BorderBrush" Value="#FF818080"></Setter>
<Setter Property="BorderThickness" Value="0,0,0,1"></Setter>
</Style>
Border thickness setter in style applies for control and it has upper precedence in style, and visual studio ignores its values in local, but foreground setter in style does not applies, when i set it locally it applies,
Why border thickness in style have upper precedence but foreground in local have upper precedence????????
I know there is a default template for labels like bellow that have a trigger for IsEnabled , that template is something like this:
<ControlTemplate TargetType="{x:Type Label}">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="True">
<ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
Can anyone help me?
Sorry for my English.

All the local styles take precedence over defined styles, so inline styles will always override other styles defined in resources.
When I run the code I found that Style's BorderThickness also get overridden by the local inline style value for BorderThickness as well.
I too would love to hear if there's a workaround for this.
I found this article as well, hope it helps Same problem with a style trigger though
EDIT:
Upon trying it few different ways I found using this method we can override the label's inline Foreground style, but I don't know whether it's the healthiest way
<Style TargetType="{x:Type Label}">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding}"
Foreground="Red" />
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<Label FontSize="50" Foreground="Black"> I am Black inline, Red on Style </Label>
This is me just editing the ContentTemplate of the Label .
Basically, this possible for Label because Label derives from ContentControl whereas TextBlock lives in the System.Windows.Controls namespace, it is not a control. It derives directly from FrameworkElement.
TextBlock are used in many other controls to show texts, including in Label.
Refer this article to know more about this

you have to change property name in style setter
<Setter Property="TextBlock.Foreground" Value="#FFEABEBE">

Related

WPF Visual inheritance

Need an advice (better from your real projects) - what is the best way to do visual inheretence in WPF?
More concrete: How to inherete window view with a statusbar?
There is no way to inherete one xaml file from another. Then, are you create User Control MyStatusbar and paste it on every page?
It is possible to create Style Template for base window and use style inheretence, however this only for simple visual properties (color, size).
Second idea is to create base DataTemplate, but there is no inheritance.
P.S. In WinForms there is base Form with status bar and some logic. After adding property
public string StatusbarText {set{baseStatusbar.Text = value;}}
it is very simple to use the property in child forms. Plus we have view inheritance with status bar.
I know how to inherete logic in WPF, but what to do with visualisation.
You could certainly create a custom Window control that adds a StatusbarText property. Alternatively, you could use a custom Style for Window, the only question there is how to pass the status bar items into your Style. For that you can use attached properties.
If you go this route, you cannot inherit your custom Style from the default one, as you need to completely redefine the ControlTemplate. A Style for Window would look like:
<ControlTemplate x:Key="WindowTemplateKey"
TargetType="{x:Type Window}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid>
<AdornerDecorator>
<DockPanel>
<StatusBar DockPanel.Dock="Bottom" ItemsSource="{Binding Tag, RelativeSource={RelativeSource TemplatedParent}}" />
<ContentPresenter/>
</DockPanel>
</AdornerDecorator>
<ResizeGrip x:Name="WindowResizeGrip"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Visibility="Collapsed"
IsTabStop="false"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Window.ResizeMode"
Value="CanResizeWithGrip"/>
<Condition Property="Window.WindowState"
Value="Normal"/>
</MultiTrigger.Conditions>
<Setter TargetName="WindowResizeGrip"
Property="Visibility"
Value="Visible"/>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Style x:Key="{x:Type Window}"
TargetType="{x:Type Window}">
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/>
<Setter Property="Background"
Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<AdornerDecorator>
<DockPanel>
<StatusBar DockPanel.Dock="Bottom" ItemsSource="{Binding Tag, RelativeSource={RelativeSource TemplatedParent}}" />
<ContentPresenter/>
</DockPanel>
</AdornerDecorator>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Window.ResizeMode"
Value="CanResizeWithGrip">
<Setter Property="Template"
Value="{StaticResource WindowTemplateKey}"/>
</Trigger>
</Style.Triggers>
</Style>
If you use the Style above, you can set the Window.Tag property to be a list of items you want displayed in the StatusBar. The biggest problem with this approach is you would need to add attached properties for things like StatusBar.ItemContainerStyle so you can customize the look of your status bar.
Same holds for if you use a DataTemplate. So i you know you only ever want single text in your StatusBar, you could use the following in the ControlTemplates above and set the Window.Tag to the string (or use an attached property).
<StatusBar DockPanel.Dock="Bottom">
<StatusBarItem Content="{Binding Tag, RelativeSource={RelativeSource TemplatedParent}}" />
</StatusBar>
It's better to use MVVM, look WPF Apps With The Model-View-ViewModel Design Pattern
You can write a base ViewModel with StatusbarText property and then inherit from the base ViewModel.
Then you can use this ViewModel property with data binding in Styles and Templates, look Customize Data Display with Data Binding and WPF
Also look at this question

Canvas with Children as a Style

Sorry if this is a dense question, but I'm looking to see if there is a way to have a style resource of Canvas in App.xaml and also have children on that Canvas and just refer to it in the Style of another canvas. The resource I envision would be something like:
<Style x:Key="Background1" TargetType="Canvas">
<Setter Property="Width" Value="500"/>
<Setter Property="Height" Value="600" />
<Setter Property="Background" Value="Red"/>
<Setter Property="Children">
<Setter.Value>
<Rectangle Canvas.Top="20" Canvas.Left="20" Width="100" Height="100" Fill="Yellow"></Rectangle>
</Setter.Value>
</Setter>
</Style>
And then calling it would be as simple as:
<Canvas Style="{StaticResource Background1}" x:Name="CanvasRoot" >
<Rectangle x:Name="PageRectangle" Canvas.Left="114" Canvas.Top="84" Height="378" Width="210" Stroke="#92D050" Fill="#C0504D" />
</Canvas>
Any thoughts on if something like this can be done. What I've done doesn't work because there is no "Children" property on Canvas.
So you want to add a child to a Canvas via a Style? I'm afraid this is simply not possible. Styles allows you to set the values of an elements dependency properties, such as Height, Background, Stroke etc ... You can also use them to set attached properties. However, the Children property you are trying to set is not a dependency property, it is the collection of children elements that describe the children of your canvas in the visual tree.
The only way to add new elements t the visual tree using styles is to add them to some controls template. Unfortunately you canot template panels (Canvas, Grid, StackPanel). You could use a ContentControl and add your rectangle as part of its template.
A ContentControl is a lookless container of a single child. See the template described here:
http://msdn.microsoft.com/en-us/library/dd334411%28VS.95%29.aspx
Here it is, templates to add a rectangle. I am not sure what layout you are trying to achieve, but it should give you the general idea
<Style TargetType="ContentControl" x:Key="myContentControl">
<Setter Property="Foreground" Value="#FF000000"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Top"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContentControl">
<Canvas>
<Rectangle Canvas.Top="20" Canvas.Left="20" Width="100" Height="100" Fill="Yellow"></Rectangle>
<ContentPresenter
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Cursor="{TemplateBinding Cursor}"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Canvas>
</ControlTemplate>
</Setter.Value>
</Setter>
<ContentControl Style={StaticResource myContentControl}>
<Canvas x:Name="CanvasRoot" >
<Rectangle x:Name="PageRectangle" Canvas.Left="114" Canvas.Top="84" Height="378" Width="210" Stroke="#92D050" Fill="#C0504D" />
</Canvas>
</ContentControl>

Datagrid checkbox styling

Hello
First sorry for my english.
I have started recently my first project on wpf. I´m styling a custom DataGrid who have been defined programatically (the xaml code doesn´t exists).
I have styled all that i need in my datagrid control except a checkbox that i wrapped inside.
The problem is that in other place of my application i defined a checkbox style how are applying correctly but i can´t apply inside my datagrid.
Actually my datagrid doesn´t throw syntax errors but when the datagrid runs the checkbox styles doesn´t apply.
The style code look like this (its defined in a stylesheet)
... <Setter Property="DataGridCheckBoxColumn.ElementStyle">
<Setter.Value>
<Style TargetType="{x:Type CheckBox}">
<Setter Property="Background" Value="Yellow"/>
<Setter Property="BorderBrush" Value="{DynamicResource NormalBorderBrush}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<BulletDecorator Background="Transparent">
<BulletDecorator.Bullet>
<Grid Width="13" Height="13">
<Border x:Name="Border" Background="Pink" BorderBrush="Black" BorderThickness="1,1,1,1" CornerRadius="2,2,2,2"/>
<Path x:Name="CheckMark" Stroke="Green" StrokeThickness="2" SnapsToDevicePixels="False" Data="M1.5000001,1.5833334 L9.7920001,9.6666667 M1.5420001,9.6666667 L9.7083333,1.5000001" Margin="1" ClipToBounds="False" StrokeEndLineCap="Round" StrokeStartLineCap="Round"/>
</Grid>
</BulletDecorator.Bullet>
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" RecognizesAccessKey="True"/>
</BulletDecorator>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>...
Its exactly the same that it`s applying in the apliccation.
I´ve read a lot about it but i can´t to apply it, i tried, also, setting the setter property to "DatagridBoundColum.ElementStyle" and also to "CellStyle" but it doesn´t work.
Any suggest??
Thank a lot.
Do it like you would do in xaml:
<UserControl.Resources>
<DataTemplate x:Key="CheckBoxTemplate">
<CheckBox Style="{StaticResource AnyResourceKeyInApplciation}"/>
</DataTemplate>
</UserControl.Resources>
<DataGrid x:Name="dataGrid" />
this.dataGrid.Columns.Add(new DataGridTemplateColumn
{
CellTemplate = this.Resources["CheckBoxTemplate"] as DataTemplate
}
);
Thanks for your Reply vorrtex.
I didn´t apply it exactly but it helped me to find the solution, however i would have liked not to modify the VB code and only to modify it the xaml style tag.
I find an object how simplify this task. The syntax it´s the following:
column2.ElementStyle = Application.Current.FindResource("CheckBoxStyle")
It´s applying style ok inside the datagrid. But actually it´s placing at left border of the cell. I´ll try to find why.
Thanks again.
You can try this
<Controls:DataGridCheckBoxColumn Header="Homme" Binding="{Binding Homme}">
<Controls:DataGridCheckBoxColumn.ElementStyle>
<Style TargetType="CheckBox" BasedOn="{StaticResource {x:Type CheckBox}}">
<Setter Property="Margin" Value="4,0,0,0"/>
</Style>
</Controls:DataGridCheckBoxColumn.ElementStyle>
</Controls:DataGridCheckBoxColumn>

DataTemplate / ContentTemplate - exchange controls

How can i solve the following (simplified) problem?
M-V-VM context. I want to show text at the UI.
In case the user has the rights to change the text, i want to use a textbox to manipulate the text.
In case the user has no rights, i want to use a label to only show the text.
My main problem: how to exchange textbox and label and bind Text resp. Content to the same property in viewmodel.
Thanks for your answers
Toni
There are a few ways of achieving this, with varying degrees of ease of reuse. You can have a DataTemplateSelector that could return the appropriate DataTemplate for a given property (depending on how this is written, you may be able to use it for each of your properties).
You could create a DataTemplate for each property, and change visibility based on a DataTrigger (this gets really annoying, as it is a lot of copy and paste).
I think the easiest way of doing this is with a specialized ControlTemplate for the TextBox. Basically, when it is disabled, instead of graying it out, you can just make it look like a TextBlock:
<ControlTemplate x:Key="PermissionedTextBox" TargetType="{x:Type TextBox}">
<Border x:Name="bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
<ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="bd" Property="BorderBrush" Value="{x:Null}" />
<Setter TargetName="bd" Property="Background" Value="{x:Null}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
Then you can use it like so:
<TextBox Text="{Binding PermissionedText}" IsEnabled="{Binding CanEdit}" />

How to make a simple hyperlink in XAML?

All I want to do is make a little hyperlink in XAML. I've tried everything. I give up.
What is the syntax for this?
<StackPanel Width="70" HorizontalAlignment="Center">
<Hyperlink Click="buttonClose_Click" Cursor="Hand"
Foreground="#555" Width="31" Margin="0 0 0 15"
HorizontalAlignment="Right">Close</Hyperlink>
<Button Width="60" Margin="0 0 0 3">Test 1</Button>
<Button Width="60" Margin="0 0 0 3">Test 2</Button>
<Button Width="60" Margin="0 0 0 3">Test 3</Button>
<Button Width="60" Margin="0 0 0 3">Test 4</Button>
</StackPanel>
Visual Studio Team: In Visual Studio 2010 I want Clippy to pop up and say "It seems you are trying to make a hyperlink" and tell me how to do it. Can't you do that with MEF? It would be retro cool, and these little "how do I do what I already know how to do in HTML" issues burn up so much time during the learning process with XAML.
You can't add a Hyperlink to a StackPanel -- you'll get a runtime error. (Actually, I'm kinda surprised it's not a compile-time error.) That's because Hyperlink doesn't live in the "controls" side of WPF with <Button> and <StackPanel> and other things that are laid out on rectangular chunks of screen and descend from UIElement. Instead, it lives in the "text" side of things, with <Bold> and <Run> and <Paragraph> and other generally texty things that word-wrap and flow in lines and paragraphs and descend from TextElement.
Once you realize that there are two separate class hierarchies with different layout behaviors, it makes sense that Hyperlink would be on the "text" side of things (makes it easy to e.g. have a paragraph with a hyperlink in the middle, and even for that hyperlink to wrap across a line break).
But no, it's not so discoverable when you're starting out.
To mix the two worlds, and use a hyperlink as a control, all you need to do is put it in a TextBlock. TextBlock is a control-ish thing (i.e., can go in a StackPanel) that contains text-ish things (i.e., can contain a Hyperlink):
<TextBlock><Hyperlink Click="buttonClose_Click">Close</Hyperlink></TextBlock>
You can use a Button with a custom control template, the code below is a limited hyperlink style button (for example it only support textual hyperlinks) but maybe it'll point you in the right direction.
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
<Style x:Key="Link" TargetType="Button">
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Foreground" Value="Blue"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<TextBlock TextDecorations="Underline"
Text="{TemplateBinding Content}"
Background="{TemplateBinding Background}"/>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Foreground" Value="Red"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
<Button Content="Click Me!" Style="{StaticResource Link}"/>
</Page>
Try this:
<TextBlock>
<Hyperlink RequestNavigate="Hyperlink_RequestNavigate"
NavigateUri="http://www.msn.com">MSN</Hyperlink>
</TextBlock>
private void Hyperlink_RequestNavigate(object sender,
System.Windows.Navigation.RequestNavigateEventArgs e)
{
System.Diagnostics.Process.Start(e.Uri.AbsoluteUri);
}
<TextBlock>
<Hyperlink NavigateUri="{Binding YourUri}" RequestNavigate="YourRequestNavigate">
<TextBlock Text="{Binding YourText}" />
</Hyperlink>
</TextBlock>
This will linkify any binded text in the nested textblock, i have not found a better way yet, i would like the first textblock to not be there if possible.
This will work for DataTemplates aswell.
You may find that if you're binding to anything other than simple text values you will need to use ContentPresenter otherwise nothing will appear, this could be true if you're binding to an XML data source.
A Property Trigger for IsMouseOver gives the text an underline.
An example where I"m binding to XML is presented below.
<Style x:Key="JobNumberStyleButton" TargetType="{x:Type Button}">
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<TextBlock>
<ContentPresenter
Margin="0,0,0,0"
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
ContentStringFormat="{TemplateBinding ContentStringFormat}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
RecognizesAccessKey="False"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<TextBlock Padding="0,0,0,0" Margin="0,0,0,0">
<Underline>
<ContentPresenter
Margin="0,0,0,0"
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
ContentStringFormat="{TemplateBinding ContentStringFormat}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
RecognizesAccessKey="False"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Underline>
</TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
You can simply use HyperlinkButton.
When it is clicked on, the URL will be displayed in your web browser:
<HyperlinkButton
NavigateUri="https://dev.windowsphone.com"
TargetName="_blank"
Content="Windows Phone Dev Center" />
Usually, the meaning of an Hyperlink is to give an anchor to send the user to another Page or generally speaking to another resource, so it's implemented in such a way and you have to specify the location for that resource like this:
<HyperLink NavigateUri="http://www.site.com">
Web Site
</HyperLink>
However, i've found this blog post with a custom TextBlock that is used as an HyperLink and supports click events.
in UWP with mvvmcross i'm using this
<HyperlinkButton Content="{Binding TextSource, ConverterParameter=MyUrl, Converter={StaticResource Language},
FallbackValue=_MyUrl}" NavigateUri="http://www.google.com" />

Resources