Reading Content property of a Button into a ConrtolTemplate in a style - wpf

I have a style for a button with a ControlTemplate something like this
<Style x:Key="ButtonStyle"
BasedOn="{x:Null}"
TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Rectangle x:Name="rectangle"
Fill="#FF04822A"
Stroke="{x:Null}" />
<TextBlock HorizontalAlignment="Center"
VerticalAlignment="Center"
FontWeight="Heavy"
Foreground="Black"
x:Name="btnText"
TextAlignment="Center" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Button Grid.Row="3"
Grid.Column="5"
Margin="4,0,4,0"
Command="{Binding ResetCommand}"
Content ="Reset Cells"
Style="{StaticResource ButtonStyle}" />
I want the TextBlock to read from the button Content every time its updated.

Add a template binding to the TextBlock:
Text="{TemplateBinding Content}"
You might just want to use a ContentPresenter instead though (as TextBlocks usually only display text).

Related

How to define a TabItem Header Template in WPF

I'm learning WPF and I read an article about Templating. So I wanted to write some code, but i got stuck.
What do I want to do? My Application has A TabControl and I want that all the tabs has the same Layout. A stackpanel and in the stackpanel an Image and a Textblock.
Now i don't know how the content can be set afterwards. Do I need a ContentPresenter?
<ControlTemplate x:Key="TabTemplate">
<StackPanel Orientation="Horizontal">
<Image></Image>
<TextBlock></TextBlock>
</StackPanel>
</ControlTemplate>
In your resource dictionary add a Style with your desired template:
<Style x:Key="CustomTabItemStyle"
TargetType="{x:Type TabItem}">
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid x:Name="Root"
Width="180"
Height="45"
Margin="0,0,0,0"
SnapsToDevicePixels="true">
<StackPanel Orientation="Horizontal">
<Image Width="90"
Margin="10"
VerticalAlignment="Center"
Source="pack://Application:,,,/img/myTabImage.png"
Stretch="Uniform" />
<TextBlock x:Name="contentPresenter"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Focusable="False"
FontSize="16"
Foreground="White"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
Text="{TemplateBinding Header}" />
</StackPanel>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Don't forget to edit your Image. If all tabs has same image then just change a Source link, otherwise, you may need another binding, e.g Content.
And then simply use this style in your TabItems:
<TabControl Margin="0,5,0,0"
FocusVisualStyle="{x:Null}">
<TabItem Header="My First Tab"
IsSelected="{Binding FirstTabItemSelected}"
Style="{DynamicResource CustomTabItemStyle}">
...
</TabItem>
<TabItem Header="My Second Tab"
IsSelected="{Binding SecondTabItemSelected}"
Style="{DynamicResource CustomTabItemStyle}">
...
</TabItem>
</TabControl>

WPF Window Chrome styling

I'm using WindowChrome class for solving problem with different icons in task bar and app header. Here is my window.style example:
<Window.Style>
<Style TargetType="{x:Type local:MainWindow}">
<Setter Property="shell:WindowChrome.WindowChrome">
<Setter.Value>
<shell:WindowChrome GlassFrameThickness="-1"
ResizeBorderThickness="4"
UseAeroCaptionButtons="True"/>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:MainWindow}">
<Grid>
<!-- This is the ContentPresenter that displays the window content. -->
<Border Margin="1 30 1 1" Background="White"
>
<ContentPresenter Content="{TemplateBinding Content}" />
</Border>
<!-- Window Title -->
<Image Margin="5" VerticalAlignment="Top" HorizontalAlignment="Left" Width="16" Height="16" Source="some.ico"></Image>
<TextBlock Margin="25 5 0 0" VerticalAlignment="Top" TextAlignment="Left"
Text="{Binding RelativeSource=
{RelativeSource TemplatedParent}, Path=Title}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Style>
When not maximized - my window looks as I want.
But when maximized(by double click/maximize button click or dock to the top) the header background is black, I can't see any buttons and my icon is out of the screen bounds. :(
Any suggestions? What i'm doing wrong in my style?

How can I access child element of any object by using style?

I'm faced with a problem about to find child element. I want to access TextBlock element inside Label. But I can't find it.
Here is my MainWindow.xaml code:
<Label x:Name="text" Style="{DynamicResource labelstyle}">
<TextBlock>asdasdasd</TextBlock>
</Label>
Here is my style code:
<Style x:Key="labelstyle" TargetType="Label">
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Label">
<Border BorderThickness="2" BorderBrush="Red">
<TextBox x:Name="textBox" Text="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type TextBlock},
AncestorLevel=2},Path=Text}">
</TextBox>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I want to bind TextBox's Text property to Label inside TextBlock's Text property. What should I do ?
I hope I made my self clear.
Thank you.
Below is a sample image:
Instead of using a TextBlock in your label, just leave it in your template and have it reference the Label Content for the text to be displayed.
Below is an example:
<Label x:Name="text" Content="asdasdasd" Style="{StaticResource labelstyle}"/>
and for the styling/template
<Style x:Key="labelstyle" TargetType="{x:Type Label}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Label}">
<Border BorderThickness="2" BorderBrush="Red">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="{TemplateBinding Content}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style>
This should provide you with the centered text in the red border you seem to be trying to achieve.
Hopefully this helps you a bit.
This will let you display text through a binding and the user will be able to select it, but not type in the TextBox. If you want to be able to also type in the TextBox, remove the IsReadOnly="True"
<Label Height="30" Width="150">
<Label.Template>
<ControlTemplate TargetType="{x:Type Label}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0"
MinWidth="26"
Margin="2"
Source="{Binding myImageSource}"/>
<TextBox Grid.Column="1"
IsReadOnly="True"
Text="{Binding myTextValue}"
Margin="5,2"/>
</Grid>
</ControlTemplate>
</Label.Template>
</Label>

WPF TextBox not displaying text with Template

so i have a TextBox, and i set a template to it, but i cannot get the text of the TextBox to display. what am i doing wrong, i followed This Question but i still do not have it working.
<UserControl.Resources>
<Style TargetType="TextBox" x:Key="txtReg">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border BorderThickness="2" CornerRadius="5" BorderBrush="Black" Background="Yellow" >
<ScrollViewer Margin="0" x:Name="PART_ContentHost"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
TextBox
<TextBox x:Name="txtHdrReg" Grid.Row="0" Grid.Column="1" FontSize="40" TextAlignment="Center" Padding="10,0" Height="60" Width="260" Text="REG" Style="{ThemeResource txtReg}" />
but still the text isn't displaying, any idea???

Setting tooltip to equal content

I'm trying to set a data grid's cell's tooltip to be equal to the text inside of a TextBlock in that cell. What I have so far is this:
<Style x:Key="CellStyle" TargetType="{x:Type DataGridCell}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="DataGridCell">
<Grid>
<TextBlock Margin="2" VerticalAlignment="Center"
HorizontalAlignment="Left" TextWrapping="Wrap" >
<ContentPresenter Content="{TemplateBinding Property=ContentControl.Content}" />
<TextBlock.ToolTip>
<ContentPresenter Content="{TemplateBinding Property=ContentControl.Content}" />
</TextBlock.ToolTip>
</TextBlock>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
However, what this does is very briefly show the tooltip and then the content in the cell is removed, so nothing shows up at all. Also, setting the tooltip from outside the Template setter is an option, but I'm not sure what the corrent binding is to do that.
My example here is for a simple label but this can be applied to other controls.
<Label Name="lblFormName" Content="Form Elements:" FontWeight="Bold" HorizontalAlignment="Left" Width="295" >
<Label.ToolTip>
<Binding ElementName="lblFormName" Path="Content"/>
</Label.ToolTip>
</Label>
Check out this link: http://msdn.microsoft.com/en-us/library/ms742167.aspx
or this link for a bunch of binding "how-to"s from MS http://msdn.microsoft.com/en-us/library/ms752039.aspx
Have you tried using RelativeSource? I heard of some issues about TemplateBinding vs. RelativeSource (WPF TemplateBinding vs RelativeSource TemplatedParent).
<ContentPresenter Content="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type YourAncestorType}, AncestorLevel=1},Path=Content}" />
Where "YourAncestorType" is the type of the parent you want to find.
Or you could also try the same approach with
<ContentPresenter Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}" />
See also: http://www.wpfwiki.com/Default.aspx?Page=WPF%20Q5.3&AspxAutoDetectCookieSupport=1
Try removing the ToolTip from the ControlTemplate and defining a separate Setter in the Style for the Tooltip.
Here is the XAML using your sample:
<Style x:Key="CellStyle" TargetType="{x:Type WpfToolkit:DataGridCell}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="WpfToolkit:DataGridCell">
<Grid>
<TextBlock Margin="2" VerticalAlignment="Center"
HorizontalAlignment="Left" TextWrapping="Wrap" >
<ContentPresenter Content="{TemplateBinding Property=ContentControl.Content}" />
<!--<TextBlock.ToolTip>
<ContentPresenter Content="{TemplateBinding Property=ContentControl.Content}" />
</TextBlock.ToolTip>-->
</TextBlock>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=Content.Text}"/>
</Style>

Resources