Adding line to a shape in XAML - wpf

I am modifying the button visual appearance in my XAML code with a hexagon. Now, I want to add 2 lines to the two outer edges of the hexagon like the image below:
https://skydrive.live.com/redir.aspx?cid=204df65b0e6e1655&resid=204DF65B0E6E1655!117&parid=204DF65B0E6E1655!107&authkey=!AEzKZRmwMNhBWxM
Can anyone tell how and where to add it ? My code is something like this
<Page.Resources>
<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Canvas>
<Polygon Canvas.Top="30" Points=
"430,0
400,32
-30,32
-60,0
-30,-32
400,-32"
Stroke="Brown" StrokeThickness="10"/>
<ContentPresenter Canvas.Left="80" Foreground="White" FontSize="40"></ContentPresenter>
</Canvas>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
<Grid Background="Black">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Button Grid.Row="1" Margin="40,-100 0,-50" HorizontalAlignment="Center">Hello World</Button>
</Grid>
I cant get the line to connect to those edges and spread all the way to the page end.
Any idea ?

Do you want this within your button style? I was able to achieve this through the XAML button control template code below.
I put separators in a grid and then put rectangles on top them to add stroke to the image.
I also added an upper margin of 2 onto the polygon to align with the rectangles.
<ControlTemplate TargetType="Button">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="500"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Rectangle Fill="White" Grid.Column="0"/>
<Rectangle Fill="White" Grid.Column="2"/>
<Separator Background="White" Grid.Column="0"/>
<Separator Background="White" Grid.Column="2"/>
<Canvas Grid.Column="1" Margin="64,2,0,0">
<Polygon Points=
"430,0
400,32
-30,32
-60,0
-30,-32
400,-32"
Stroke="Brown" StrokeThickness="10"/>
<ContentPresenter Canvas.Left="80" Foreground="White" FontSize="40"/>
</Canvas>
</Grid>
</ControlTemplate>

Related

Get Header name

Hello I am a bit lost with the control Templates, I have an expander and some control-styles that apply onto the Expander.
So the idea is to let the User insert the header
<Expander Name="MyExpanderExpander" Style="{StaticResource MyExpanderNewGeneration}" Header="UserChoice" OverridesDefaultStyle="True" VerticalAlignment="Top" Margin="0,0,0,0" Height="210">
So now the Style : MyExpanderNewGeneration should get the header Name : UserChoic
The ToggleButton has to get the Header Name : UserChoice and here is my problem ..but how to do it?
my Style applying is
<Style TargetType="Expander" x:Key="MyExpanderNewGeneration" BasedOn="{StaticResource BaseControlStyle}" >
<!--x:Key="GroupBoxStyle"-->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Expander">
<Grid>
<!--Grid Rows split the GroupBox into two areas -->
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--Header area-->
<Border Name="HeaderArea"
Grid.Row="0"
Background="Transparent"
BorderBrush="Transparent"
BorderThickness="1"
CornerRadius="2,2,0,0" >
<ToggleButton x:Name="ExpanderButton"
Grid.Row="0"
Grid.Column="0"
Margin="0,0,0,0"
VerticalAlignment="Top"
Template="{StaticResource TestToggleButton}"
Content="{TemplateBinding Header}"
IsChecked="{Binding Path=IsExpanded, RelativeSource={RelativeSource TemplatedParent}}"
OverridesDefaultStyle="True">
</ToggleButton>
Herer I want to get the UserChoice Name.
<ControlTemplate x:Key="TestToggleButton" TargetType="{x:Type ToggleButton}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Foreground="White" Width="300" Grid.Column="0" FontSize="15"
HorizontalAlignment="Left" FontWeight="Normal" Something={HEADER???}
How to solve this?
Since you are setting Content="{TemplateBinding Header}" in your ExpanderButton, you will need to bind to the Content property inside your TestToggleButton style's control template:
<ControlTemplate x:Key="TestToggleButton" TargetType="{x:Type ToggleButton}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label
...
Content={TemplateBinding Content} />
...
</Grid>
</ControlTemplate>

The width of StackPanel inside the button is very narrow.(WPF)

I want to make a button with an image similar to the following:
For which I have written the following in xaml:
<Button
Style="{DynamicResource BotonRedondo2}"
Width ="AUTO"
Cursor="Hand"
Background="#3b5998"
Grid.Column="0">
<StackPanel Width ="Auto" Orientation="Horizontal" >
<Image HorizontalAlignment="Left" Source="/Test;component/Imagenes/face.png"/>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="LOGIN WITH XXXXX" />
<StackPanel>
</Button>
But the result is as follows:
The width of the StackPanel does not match the width of the button.
Any suggestions on how to solve the problem?
Comments or questions are welcome
UPDATE
Maybe I should indicate that the button is in a column of a grid as follows:
<Grid
Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button
Style="{DynamicResource BotonRedondo2}"
Width ="AUTO"
Cursor="Hand"
Background="#3b5998"
Grid.Column="0">
<StackPanel Width ="Auto" Orientation="Horizontal" >
<Image HorizontalAlignment="Left" Source="/Test;component/Imagenes/face.png"/>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="LOGIN WITH XXXXX" />
</StackPanel>
</Button>
<Button
Style="{DynamicResource BotonRedondo2}"
Grid.Column="1"
Width ="Auto"
Background="Orange"
Content="LOGIN2"
Margin="3"/>
</Grid>
If I remove "Auto", the button looks like this:
UPDATE
The style that applies to the button is as follows:
<Style TargetType="Button" x:Key="BotonRedondo2">
<Setter Property="Background" Value="Blue"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Height" Value="35"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border BorderThickness="0"
Background="{TemplateBinding Background}"
CornerRadius="4">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
StackPanel in Horizontal orientation stacks items next to each other. It basically doesn't care about the HorizontalAlignment of items inside it.
You can use a Grid instead:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" HorizontalAlignment="Left" Source="/Test;component/Imagenes/face.png"/>
<TextBlock Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center" Text="LOGIN WITH XXXXX" />
</Grid>
The above will give you the desired look.
You need to remove Width="Auto" from the Button and to set Button's property HorizontalContentAlignment="Stretch".
Also, consider using DockPanel or Grid instead of StackPanel:
<Button HorizontalContentAlignment="Stretch">
<DockPanel>
<Image Source="/Test;component/Imagenes/face.png"/>
<TextBlock
VerticalAlignment="Center"
HorizontalAlignment="Center"
Text="LOGIN WITH XXXXX" />
</DockPanel>
</Button>
In the style of the button it should be written like this:
CornerRadius="4">
<ContentPresenter HorizontalAlignment="Stretch" VerticalAlignment="Center"/>

Custom style tooltip and binding to button WPF with code xaml?

I would like to create a style for the tooltip and use it always binding to each button.
I can only do so from XAML?
I have done this for now:
<Window.Resources>
<Style x:Key="{x:Type ToolTip}" TargetType="{x:Type ToolTip}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToolTip}">
<Grid Width="200" Height="Auto" MinHeight="80">
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="1" FontWeight="Bold"
HorizontalAlignment="Left" VerticalAlignment="Center"
Text="{Binding Path=TitleTT}"/>
<Image Grid.Column="0" Grid.RowSpan="2" Source="{Binding Path=ImageTT}"
HorizontalAlignment="Stretch" VerticalAlignment="Center"/>
<TextBlock Grid.Row="1" Grid.Column="1" TextWrapping="Wrap" Margin="2"
HorizontalAlignment="Left" VerticalAlignment="Center"
Text="{Binding Path=DescriptionTT}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
Now, I want to build a button in another user control.
What should I do?
What's wrong? why can not join anything?
Thanks for the help.
Code Button:
<Button Name="button_conf" Content="{DynamicResource Button_Confirm}" Margin="18,10"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Click="button_conf_Click">
<Button.ToolTip>
<ToolTip Style=ToolTip TitleTT="{DynamicResource ToolTip_title__confirm_defsce}"
ImageTT="/Images/xsd.jpg" DescriptionTT="The button confirm....:"/>
</Button.ToolTip>
</Button>
I can see at least the following two typos:
1.
<Style x:Key="{x:Type ToolTip}" TargetType="{x:Type ToolTip}"
should be
<Style x:Key="ToolTipStyle" TargetType="{x:Type ToolTip}"
Of course, you can use another name than ToolTipStyle.
2.
<ToolTip Style=ToolTip
should be
<ToolTip Style="{StaticResource ToolTipStyle}"
Apart from that, the properties TitleTT, ImageTT and DescriptionTT do not exist on the ToolTip control.

16x16 pixel images in RibbonApplicationMenuItem gets stretched

I am having a ribbon application menu that looks like this:
<ribbon:RibbonWindow>
<DockPanel>
<ribbon:Ribbon DockPanel.Dock="Top">
<ribbon:Ribbon.ApplicationMenu>
<ribbon:RibbonApplicationMenu>
<ribbon:RibbonApplicationMenuItem Header="Users"
ImageSource="Users16x16.png"
Command="{Binding FooBinding}"/>
</ribbon:RibbonApplicationMenu>
</ribbon:Ribbon.ApplicationMenu>
</ribbon:Ribbon>
</DockPanel>
</ribbon:RibbonWindow>
The resulting image looks like this, stretched.
So how do I have a ribbon application menu item with a height that adapts to the image size instead of stretching?
Change the control template like:
<ribbon:RibbonApplicationMenuItem Command="{Binding FooBinding}">
<ribbon:RibbonApplicationMenuItem.Template>
<ControlTemplate>
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="Users16x16.png"/>
<TextBlock Grid.Column="1">Users</TextBlock>
</Grid>
</ControlTemplate>
</ribbon:RibbonApplicationMenuItem.Template>
</ribbon:RibbonApplicationMenuItem>
If you want to use control template as Style in your dictionary:
<Style x:Key="16x16ImageStyle" TargetType="{x:Type ribbon:RibbonApplicationMenuItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ribbon:RibbonApplicationMenuItem}">
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Image VerticalAlignment="Center" HorizontalAlignment="Center" Stretch="None"
Grid.Column="0" Source="{TemplateBinding ImageSource}"/>
<TextBlock Grid.Column="1" Text="{TemplateBinding Header}"></TextBlock>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
and recall it in your ribbon:
<ribbon:RibbonApplicationMenuItem Header="Users"
ImageSource="Users16x16.png"
Command="{Binding FooBinding}"
Style="{StaticResource 16x16ImageStyle}"/>

Style a border with a different brush color for each corner

I have created a static resource defining the border of a specific item in my xaml, but I can't find a good way to define a unique color for each side!
xaml:
<Border Style="{StaticResource SidePanelBorder}">
<!-- rest of the xaml -->
</Border>
StaticResource:
<Style x:Key="SidePanelBorder">
<Setter Property="Control.BorderBrush" Value="#FF363636" />
<Setter Property="Control.BorderThickness" Value="1" />
</Style>
But I want to define one color for each side of the border, and eventually also a different Border thickness.
Any good techniques out there doing this?
Seems very hacky, but you could define borders within borders, and make only 1 side have a thickness. For example
<Border BorderThickness="0,0,0,10" BorderBrush="Green">
<Border BorderThickness="0,0,10,0" BorderBrush="Blue">
<Grid>
<Button>Hello</Button>
</Grid>
</Border>
</Border>
would give a green border on the bottom and a blue border to the right. Isn't the prettiest piece of Xaml though.
Another solution using one Border and a VisualBrush, allowing setting the Border's CornerRadius and BorderThickness:
<Border BorderThickness="10" CornerRadius="10" HorizontalAlignment="Right" Height="150" VerticalAlignment="Bottom" Width="150" Margin="0,0,92.666,42.667">
<Border.BorderBrush>
<VisualBrush>
<VisualBrush.Visual>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Path x:Name="ColoredBorderLeft" Data="M0,0 L0,0 1,0.5 L1,0.5 0,1" Fill="Blue" Stretch="Fill" Grid.RowSpan="2"/>
<Path x:Name="ColoredBorderRight" Data="M1,0 L1,0 0,0.5 L0,0.5 1,1" Fill="Red" Stretch="Fill" Grid.Column="1" Grid.RowSpan="2"/>
<Path x:Name="ColoredBorderTop" Data="M0,0 L0,0 0.5,1 L0.5,1 1,0" Fill="Green" Stretch="Fill" Grid.ColumnSpan="2"/>
<Path x:Name="ColoredBorderBottom" Data="M0,1 L0,1 0.5,0 L0.5,0 1,1" Fill="Yellow" Stretch="Fill" Grid.Row="1" Grid.ColumnSpan="2"/>
</Grid>
</VisualBrush.Visual>
</VisualBrush>
</Border.BorderBrush>
</Border>
The Grid is needed to prevent the tips of the triangle Paths to "push through" into the border.
The Path.Name's can be used for DataBinding or setting the color from code behind.
you can have a DockPanel and can put 4 Borders inside it, each docked to different side.
like:
<DockPanel LastChildFill="true">
<Border DockPanel.Dock="Left" Background="Red"/>
<Border DockPanel.Dock="Top" Background ="Blue"/>
<Border DockPanel.Dock="Right" Background ="Yellow"/>
<Border DockPanel.Dock="Bottom" Background ="Green"/>
<Grid>
...........your control here
</Grid>
</DockPanel>
If you use a Grid you can have Border's overlay on one another to achieve the same affect. Just set the border thickness of the border color you want to show and have the other border thickness be 0.
<UserControl.Resources>
<Style x:Key="GreenBorder" TargetType="Border">
<Setter Property="BorderBrush" Value="Green" />
<Setter Property="BorderThickness" Value="1,1,1,0" />
</Style>
<Style x:Key="RedBorder" TargetType="Border">
<Setter Property="BorderBrush" Value="Red" />
<Setter Property="BorderThickness" Value="0,0,0,1" />
</Style>
</UserControl.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border Grid.Column="0" Grid.Row="0" Style="{StaticResource GreenBorder}">
<!-- Content goes here -->
</Border>
<Border Grid.Column="0" Grid.Row="0" Style="{StaticResource RedBorder}">
</Border>
</Grid>
This will give a Green border to the left, top and right borders, but a Red border to the bottom border of the Grid cell.
there's no easy way to do this without writing your own control or subclassing border

Resources