this is a two part question that probbably have a similar answer.
I want to create in a resource dictionary a style for a label that contains first an image and then the text. The text, as a TextBlock has it's own style (had no problems there). Here is what I have
Label Style:
<Style x:Key="LabelStyle" TargetType="Label">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Label">
<TextBlock Style="{StaticResource TextBlockStyle}">
</TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
TextBlockStyle:
<Style x:Key="TextBlockStyle" TargetType="{x:Type TextBlock}">
<Setter Property="Margin" Value="25 0 0 2.5"/>
<Setter Property="Width" Value="Auto"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="TextDecorations" Value="Underline"/>
<Setter Property="Foreground" Value="Blue"/>
<Setter Property="Cursor" Value="Hand"/>
</Trigger>
</Style.Triggers>
</Style>
Now my problem is when I add a new label to my Control (ex: Window) and specify the text (ex: Create), no text is shown.Something like:
<Label Style="{StaticResource LabelStyle}">Create</Label>
The text Create does not show, however if I put in my LabelStyle->TextBlock->text it shows, but it's no good since I want to change it for different labels. Is there a way to bind my Label text to my (Inside Style) TextBlock.Text???
My other question is the same, but for images, and Image.Source.
Thanks :-)
EDIT:
This is what I have now with H.B. answer implemented
<Style x:Key="LabelStyle" TargetType="Label">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Label">
<Grid>
<StackPanel Orientation="Horizontal">
<Image Source="/Resources/Create.png" />
<TextBlock Style="{StaticResource TextBlockStyle}" Text="{TemplateBinding Content}"/>
</StackPanel>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Note that this is in the Resource Dictionary. For the TextBlock it works great. But for the image it's a different story. I want the same as the 'Text="{TemplateBinding Content}' but for the Image.Source and set it's path in my control when I add the label. Probabbly since it's multiple content I'll have to write more code than I'd like, but I'll settle for the easiest, cleanest answer.
H.B. thanks again and as for the hyperlink, this is still in development, it's not going to be in anyway a hyperlink, just some custom menu button with some animation so it's not so boring for the user :P
Your Label.Template no longer links the Content property of the Label (which you set to "Create") to any internal part. To fix this you can for example bind the TextBlock.Text like this:
<ControlTemplate TargetType="Label">
<TextBlock Style="{StaticResource TextBlockStyle}"
Text="{TemplateBinding Content}"/>
</ControlTemplate>
(I just noticed that you make the Label look like a hyperlink, you do realize that there already is a class for that, right?)
Related
I've tried all kinds of template binding and such to get this to work, but if I use this style on a control, the internal textbox control doesn't show focus.
I'm doing this because I want to set an error template that wraps around the textbox and the spot reserved for displaying units.
Now, typing in the box correct updates the text inside. And clicking on it will show the highlighted border and input caret, but tabbing into it won't.
<Style x:Key="Special" TargetType="{x:Type TextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<DockPanel
LastChildFill="True"
Visibility="Visible">
<Border
Name="PART_UnitContainer"
DockPanel.Dock="Right"
Visibility="Collapsed">
<Label
Content="ft"
Style="{DynamicResource UnitLabel}"
/>
</Border>
<TextBox Name="PART_Control" Text="{Binding Text, RelativeSource={RelativeSource TemplatedParent}}"/>
</DockPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter TargetName="PART_UnitContainer" Property="Visibility" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Initially I set the whole control as no tab stop, and internal one with tabstop, but apparently you also have to set the tab navigation to continue. I didn't when I tried playing with navigation, so I overlooked this setting.
<Style x:Key="Special" TargetType="{x:Type TextBox}">
<Setter Property="KeyboardNavigation.TabNavigation" Value="Continue"/>
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="Template">
<ControlTemplate>
...
<Text IsTabStop="True" Name="PART_Control" ...
...
</ControlTemplate>
</Setter>
</Style>
However, this little trick doesn't work for shift-tab out of an editable combobox. I'll update the answer if I figure it out.
For comboboxes you have to do it differently. You don't set TabNavigation to Continue, and you don't set IsTabStop on internal combobox to true.
See
<Style x:Key="Special" TargetType="{x:Type ComboBox}">
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="Template">
<ControlTemplate>
...
<ComboBox Name="PART_Control" ...
...
</ControlTemplate>
</Setter>
</Style>
My first steps in WPF and C# and i don't get it to work... :(
I have an application with two grids inside one window. I have to change the style of the first grid, so i started reading and reached using ControlTemplate.
My Grid now looks as i wanted it. But i only want that the first grid looks this way. the second one on the same page should have another style.
Is it possible to bind the controltemplate only on one grid. Maybe by name or soemthing identifying?
My ControlTemplate Code for now i have written in window.resources looks:
<Style TargetType="{x:Type TabItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid>
<Border
Name="Border"
Margin="0,0,0,0"
Background="Black"
BorderBrush="Black"
BorderThickness="0,2,0,0"
CornerRadius="0,0,0,0" >
<ContentPresenter x:Name="ContentSite"
VerticalAlignment="Center"
HorizontalAlignment="Center"
ContentSource="Header"
Margin="0,0,0,20"
RecognizesAccessKey="True"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Border" Property="BorderBrush" Value="#FF454E54" />
<Setter TargetName="Border" Property="Background" Value="#FF0A3651" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Border" Property="BorderBrush" Value="White" />
<Setter TargetName="Border" Property="Background" Value="#FF454E54" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
You could give the Style or ControlTemplate an x:Key ( <Style x:Key="key" TargetType="{x:Type TabItem}"> ) and apply it to the element you want by setting the element's Style or Template property like this:
<TabItem Style="{StaticResource key}">
A Style without an x:Key is implicit and will be applied to all elements whose type matches the specified TargetType of the Style.
Instead of writing your template under Window.Resources do it under your Grid.Resources
Try this. All this is doing is setting the style of the TabItem directly.
<TabItem> <!-- This is your TabItem control -->
<TabItem.Style>
<Style TargetType="{x:Type TabItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<!-- ControlTemplate here -->
</Controltemplate
</Setter.Value>
</Setter>
</Style>
</TabItem.Style>
</TabItem>
I'm trying to style an element in WPF which displays a yellow border around anything thats in it and shows a tool-tip when the cursor is over it. The problem is that I don't have much of an idea how to do this and anything I tried does not seem to work.
Here is what I have until now:
<Style x:Key="HistoryElementStyle"
TargetType="{x:Type Control}">
<Setter Property="BorderBrush"
Value="Yellow"/>
<Setter Property="BorderThickness"
Value="1.5" />
<Setter Property="CornerRadius"
Value="2" />
<Setter Property="ToolTip">
<Setter.Value>
<ToolTip Template="{StaticResource HistoryTooltipTemplate}" />
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ContentPresenter x:Name="PART_Content"
Width="Auto"
HorizontalAlignment="Stretch"
ContentSource="Content"
IsEnabled="{TemplateBinding IsEnabled}" />
</Setter.Value>
</Setter>
</Style>
Visual Studio complains that the ContentPresenter is an invalid type.
Cheers
AC
You must wrap the ContentPresenter around a <ControlTemplate TargetType="Control" /> to match the type of the Control.Template property.
I'd try adding the DataTempalte tag around the ContentPresenter (sorry, I cannot test from where I am writing this).
If I have the following style defined:
<UserControl.Resources>
<Style TargetType="TextBlock" x:Key="ProblemStyle">
<Setter Property="FontSize" Value="40"/>
<Setter Property="FontWeight" Value="Bold"/>
</Style>
</UserControl.Resources>
Then when I have a ContentPresenter data bound to a string, in WPF I can get it to style the text as required with the following XAML:
<ContentPresenter Content="{Binding Problem}">
<ContentPresenter.Resources>
<Style TargetType="TextBlock" BasedOn="{StaticResource ProblemStyle}" />
</ContentPresenter.Resources>
</ContentPresenter>
However, in Silverlight, this doesn't work. Is there a way that works for both?
Use the TextElement Attached property. You will not be able to set a style, but most of the properties that effects the Textblock are there..
<ContentPresenter x:Name="ContentPresenter"
ContentSource="Header"
HorizontalAlignment="Left"
TextElement.FontFamily="Segoe UI"
TextElement.FontSize="12"
TextElement.FontWeight="Bold"
TextElement.Foreground="White"
RecognizesAccessKey="True" />
First:
Make sure that your style "ProblemStyle" is being loaded before the application tries to render the ContentPresenter. In Silverlight, the order the styles are defined makes a difference, and if it has not been loaded first then it may not be reading anything.
Ok, I am going to run on some assumptions here, the first one being that you are using a ContentControl to display something and that the ContentPresenter is inside of this control.
But why not create a Style for the ContentControl?
<Style x:key="ProblemStyle" TargetType="ContentControl">
<Setter Property="FontSize" Value="40"/>
<Setter Property="FontWeight" Value="Bold"/>
</Style>
Then your ContentControl would have the Style set to the StaticResource of "ProblemStyle".
Since by default the template of a ContentControl has the ContentPresenter - or you can define the ContentPresenter template in the style as well:
<Style x:key="ProblemStyle" TargetType="ContentControl">
<Setter Property="FontSize" Value="40"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContentControl">
<Border>
<ContentPresenter Content="{TemplateBinding Content}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The template there is just as a placeholder to give an idea of where it would/could be located.
I have a WPF application (.NET 3.0, VS2008) that displays data in a tab control. Custom colors are required on virtually all controls in this application : basically white foreground and green background.
My problem is that when an XP theme (say Luna) is active, it is automatically applied to render controls so that my white text is written on ... a white background. For instance on the active tab item header :
I have tried :
to remove the embedded manifest file from the generated application (in the project properties) : useless.
to force the use of the Windows Classic theme in the application resources :
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/PresentationFramework.Classic;V3.0.0.0;31bf3856ad364e35;component/themes/classic.xaml" />
</ResourceDictionary.MergedDictionaries>
This last attempt worked great for all controls, except the tab control which still displays as above.
Any idea ?
Update : I am suspecting this behaviour is due to the custom style I have to apply to the tab control :
<Window.Resources>
<Style x:Key="Custom">
<Setter Property="Control.Background" Value="#FF47C7C8" />
<Setter Property="Control.Foreground" Value="White" />
</Style>
<Style TargetType="TabControl" BasedOn="{StaticResource Custom}" />
</Window.Resources>
So how can I get the classic theme with custom colors ?
Your best bet, to ensure a consistent behavior and appearance across operating systems, would be to re-template the TabItem control and then use a Trigger to modify a part of your new template when a TabItem is selected. Try something like the following:
<Grid>
<Grid.Resources>
<Style x:Key="Custom">
<Setter Property="Control.Background" Value="#FF47C7C8"/>
<Setter Property="Control.BorderBrush" Value="#FF47C7C8"/>
<Setter Property="Control.Foreground" Value="White"/>
</Style>
<Style BasedOn="{StaticResource Custom}" TargetType="TabControl"/>
<Style TargetType="TabItem">
<Setter Property="Foreground" Value="White"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid>
<Border
Name="Border"
Background="#FF47C7C8"
BorderBrush="#FFFFFF"
BorderThickness="1,1,1,1"
CornerRadius="2,2,0,0">
<ContentPresenter
x:Name="ContentSite"
HorizontalAlignment="Center"
Margin="12,2,12,2"
VerticalAlignment="Center"
ContentSource="Header"
RecognizesAccessKey="True"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Panel.ZIndex" Value="100"/>
<Setter TargetName="Border" Property="Background" Value="#FF47C7C8"/>
<Setter TargetName="Border" Property="BorderThickness" Value="1,1,1,0"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Grid.Resources>
<TabControl>
<TabItem Header="Item 1"/>
<TabItem Header="Item 2"/>
<TabItem Header="Item 3"/>
<TabItem Header="Item 4"/>
</TabControl>
Bon chance!
Why don't you use the WPF Themes from the WPF Futures project!
WPF Themes
alt text http://i3.codeplex.com/Project/Download/FileDownload.aspx?ProjectName=wpf&DownloadId=62497