I have two button with the code in xaml is:
<Button Grid.Row="0" Grid.Column="2" Style="{StaticResource styleInfomationButton}" />
<Button Grid.Row="1" Grid.Column="2" Style="{StaticResource styleInfomationButton}" />
They're same style, but in runtime they were presented differently:
Here the image how the form showed:
Style applied:
<Style x:Key="styleInfomationButton" TargetType="Button">
<Setter Property="Width" Value="22" />
<Setter Property="Height" Value="22" />
<Setter Property="Content">
<Setter.Value>
<TextBlock FontWeight="ExtraBold" Foreground="White">?</TextBlock>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid Width="20" Height="20">
<Ellipse Fill="#81A9F0" />
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
When I tried the above code, it failed at runtime with the error:
Specified element is already the logical child of another element. Disconnect it first
Then, I looked at the code again and see you are setting Content property in the style. When you tried to apply the Style to two buttons, WPF tries to set the same TextBlock element as Content for the two buttons - this can't work. In WPF, for any element, you can only have one logical parent.
Update your style to the following, to get the desired behavior:
<Style x:Key="styleInfomationButton" TargetType="{x:Type Button}">
<Setter Property="Width" Value="22" />
<Setter Property="Height" Value="22" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid Width="20" Height="20">
<Ellipse Fill="#81A9F0" />
<<TextBlock FontWeight="ExtraBold" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center">?</TextBlock>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Very good article on Understanding the Visual Tree and Logical Tree in WPF
Related
I wonder if there is a way to do it for all the future buttons and other controls or do i need to make a solution for each control/button ? And how to do it ?
I want to disable the mouse hove highlight.
<Button x:Name="btnTest" Content="Start Watching" HorizontalAlignment="Left" Margin="14,241,0,0" VerticalAlignment="Top" Width="109" RenderTransformOrigin="0.484,-0.066" Height="30" FontSize="16" Background="#FFFB0000" Click="btnTest_Click"/>
<TextBox HorizontalAlignment="Left" Height="30" Margin="14,175,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="644"/>
<Button Content="Browse" Margin="673,175,18,0" VerticalAlignment="Top" RenderTransformOrigin="-0.111,0.769" Height="30" FontSize="16"/>
Add it to your ResourceDictionary:
<Style TargetType="Button">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="border"
BorderThickness="1"
Padding="4,2"
BorderBrush="DarkGray"
CornerRadius="3"
Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="border" Property="BorderBrush" Value="Black" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And since Style has no key it will be on all the buttons
You'll need to create a style. if you want it to be applied through your whole app, you'll need to put it into your "app.xaml" file (within an application.Resources).
Bellow is an example of how to do it. I added some stuff like setters to illustrate that you can add properties, you could also add triggers and many things.
Not setting a "x:key" to your style will make them the default one (thus overriding the basic one), as the one below, if you wish to have a collection of styles, give them keys.
`<Style TargetType="{x:Type Button}">
<Setter Property="Background"
Value="Transparent" />
<Setter Property="BorderThickness"
Value="0" />
<Setter Property="Cursor"
Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center">
</ContentPresenter>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>`
I am new to WPF and I created the following simple style example. But it doesn't work properly and button's content doesn't show although I can still click on it. Can anyone tell me why it is broken?
<Window.Resources>
<Style TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border BorderBrush="Blue"
BorderThickness="5"
Background="Aqua"
Width="80"
Height="40">
<ContentPresenter></ContentPresenter>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="Grid" x:Name="GridWithMarginStyle">
<Setter Property="Margin" Value="12"></Setter>
</Style>
</Window.Resources>
<StackPanel>
<StackPanel.Resources>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource {x:Type Button}}">
<EventSetter Event="Button.Click" Handler="ButtonHandler" />
<Setter Property="Background" Value="Red"></Setter>
<Setter Property="Foreground" Value="White"></Setter>
</Style>
</StackPanel.Resources>
<Button Name="OkBtn">OK</Button>
<Button Name="CancelBtn" Click="CancelBtn_Click">Cancel</Button>
</StackPanel>
You are using the BasedOn property in the correct way. The problem is that your ContentPresenter is not binded to the control it renders (i.e. the button).
Just try to replace your ControlTemplate XAML with this one:
<ControlTemplate TargetType="{x:Type Button}">
<Border BorderBrush="Blue"
BorderThickness="5"
Background="Aqua"
Width="80"
Height="40">
<ContentPresenter Content="{TemplateBinding Content}" />
</Border>
</ControlTemplate>
By using TemplateBinding you can bind the ContentPresenter to the Content property of your templated control.
I need to change the style of a textblock that it is inside a button..
here are my two styles:
<Style x:Key="btnStyleLR" TargetType="TextBlock">
<Setter Property="FontFamily" Value="Segoe UI Light" />
<Setter Property="FontSize" Value="40" />
<Setter Property="Padding" Value="0,20,0,20" />
</Style>
<Style x:Key="btnStyleLROverride" BasedOn="{StaticResource btnStyleLR}" TargetType="TextBlock">
<Setter Property="FontSize" Value="10" />
<Setter Property="Padding" Value="0,10,0,10" />
</Style>
and then:
<Style x:Key="btnLoginRegister" TargetType="Button">
<Setter Property="Width" Value="400" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Border x:Name="brd"
BorderBrush="Orange"
BorderThickness="1"
CornerRadius="6">
<TextBlock HorizontalAlignment="Center"
Style="{TemplateBinding Tag}"
Text="{TemplateBinding Content}" />
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I bind the style in the tag property of the button pero it is not works.
then I have two buttons that I need to change de textblock style:
<Button x:Name="loginBtn"
Style="{StaticResource btnLoginRegister}"
Tag="btnStyleLROverride"
Content="Login" />
and the other:
<Button x:Name="registerBtn"
Content="Register"
Tag="btnStyleLR"
Style="{StaticResource btnLoginRegister}" />
is there another way to change the style with bind that works? thanks
You shouldn't destroy a button's template like that, unless it's only for the purpose of this question. The simple solution to your problem is to simply set the TextBlock as the button's content and then you can change its style without hacking through the templates.
In Tag you have to provide resource value, not string. It should be:
<Button x:Name="loginBtn"
Style="{StaticResource btnLoginRegister}"
Tag="{StaticResource btnStyleLROverride}"
Content="Login" />
Do it same way for other button.
As far as I understood your requirements:
You have two Buttons ("Login" and "Register") which need to be visually reduced (should not use visual states) and which have their own "text style" each (but maybe sharing a base style)? Is this correct?
If this is the case I recommend two different Button Styles (maybe sharing the same base style):
<Button x:Name="loginBtn" Content="Login"
Style="{StaticResource LoginButtonStyle}"/>
<Button x:Name="registerBtn" Content="Register"
Style="{StaticResource RegisterButtonStyle}"/>
And your styles:
<Style x:Key="PlainButtonStyle" TargetType="Button">
<Setter Property="FontFamily" Value="Segoe UI Light"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border BorderBrush="Orange" BorderThickness="1" CornerRadius="6">
<TextBlock Text="{TemplateBinding Content}"
Padding="{TemplateBinding Padding}"
HorizontalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="LoginButtonStyle"
BasedOn="{StaticResource PlainButtonStyle}" TargetType="Button">
<Setter Property="FontSize" Value="10"/>
<Setter Property="Padding" Value="0,10,0,10"/>
</Style>
<Style x:Key="RegisterButtonStyle"
BasedOn="{StaticResource PlainButtonStyle}" TargetType="Button">
<Setter Property="FontSize" Value="40"/>
<Setter Property="Padding" Value="0,20,0,20"/>
</Style>
Properties like FontSize and FontFamily are inherited.
Can I make a tooltip style which can be applied to all tooltips for every control?
I tried this but I cant get the content (Tooltip text) in style, it is showing empty text in tooltip:
<Style TargetType="{x:Type ToolTip}" >
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="HasDropShadow" Value="True" />
<Setter Property="Foreground" Value="White" />
<Setter Property="FontSize" Value="12" />
<Setter Property="Placement" Value="Bottom" />
<Setter Property="VerticalOffset" Value="0" />
<Setter Property="Padding" Value="8" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToolTip}" >
<StackPanel Margin="7,1" >
<Border Background="#FFF7F7CC" CornerRadius="1" >
<TextBlock Margin="1" Foreground="Black" HorizontalAlignment="Center" VerticalAlignment="Top" Text="{TemplateBinding ToolTip}"/>
</Border>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
For Using this style I have to put a seperate Tooltip tag in control, eg to apply tooltip to border,
<Border>
<Border.ToolTip>
<ToolTip ToolTip="This is tooltip text" />
</Border.ToolTip>
........
.........
</Border>
but is there any way where tooltipstyle applies to all control with tooltip mentioned in same tag.
eg.
<Border BorderBrush="Transparent" Background="Transparent" Cursor="Help" ToolTip="This is Tooltip" >
.....
.....
</Border>
let me know if any further details are required.
Thanks in Anticipation.
Yes Your approach will work. But a small change is needed in the Control Template. Replace the TextBlock with ContentPresenter.
<ControlTemplate TargetType="{x:Type ToolTip}" >
<StackPanel Margin="7,1" >
<Border Background="#FFF7F7CC" CornerRadius="1" >
<ContentPresenter Margin="1" HorizontalAlignment="Center" VerticalAlignment="Top" />
</Border>
</StackPanel>
</ControlTemplate>
I am using Silverlight for embedded windows and i have a simple radiobutton style
<Style TargetType="RadioButton" x:Key="SettingsTab">
<Setter Property="Width" Value="95"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RadioButton">
<Grid x:Name="RootElement">
<Image x:Name="Ozadje1" Source="settings_backgroun.png"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Now i want to put 2 textblock above that like you can see on 2nd image.
this is the image i use in style:
Because i am new to silverlight i have a few problems with this, so i hope someone can point me in right direction.
Please keep in mind that silverlight for embedded windows is Silverlight 3 without some components.
If all you're doing is adding the TextBlock's than this should accomplish it, (as hoping that Embedded Windows will allow it.)
<Style TargetType="RadioButton" x:Key="SettingsTab">
<Setter Property="Width" Value="95"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RadioButton">
<Grid x:Name="RootElement">
<Image x:Name="Ozadje1" Source="settings_backgroun.png"/>
<TextBlock Text="LIM" Foreground="Orange" VerticalAlignment="Top" HorizontalAlignment="Center" Margin="0,5,0,0" />
<TextBlock Text="3.5mA" HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="0,0,0,5"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>