How to create a speech bubble in UWP? - c#

I'm creating a chat application and would like to create the typical speech bubble that contains each message. I created a Path object in Blend (in XAML) like this:
The problem is that the path is has designed to have a specified width and height and I would like it to wrap around the text without stretching, so it won't look deformed, like a border does.
How can I make it behave like I want?

You may use Polygon in combination with StackPanel:
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Left"
Padding="6"
>
<Polygon Points="0,0 15,0 15,15"
Fill="LightGray"
Margin="0,10,0,0"
/>
<Border Background="LightGray"
CornerRadius="3"
Padding="6"
VerticalAlignment="Top"
>
<TextBlock Text="Text"
TextWrapping="WrapWholeWords"
Width="100"
Height="50"
/>
</Border>
</StackPanel>
which looks like this:
EDIT:
Version with border:
<Grid HorizontalAlignment="Left"
Padding="6"
>
<Polygon Points="0,0 15,0 15,15"
Fill="LightGray"
Stroke="Black"
Margin="0,10,0,0"
/>
<Border Background="LightGray"
BorderBrush="Black"
BorderThickness="0.5"
CornerRadius="3"
Padding="6"
Margin="14,0,0,0"
VerticalAlignment="Top"
>
<TextBlock Text="Text"
TextWrapping="WrapWholeWords"
Width="100"
Height="50"
/>
</Border>
<Polygon Points="0,0 15,0 15,15"
Fill="LightGray"
Margin="0,10,0,0"
/>
</Grid>
This is probably not the easiest and the best way how to do this, maybe Path will be better to do this, but it works:

Here is a Custom control that declares a Dependency Property for the Text and reuse some properties of the base control in its template (Background, Width, Heigth).
First the class definition: (SpeechBubbleControl.xaml.cs)
[TemplatePart(Name = PartBubbleText, Type = typeof(TextBlock))]
public sealed partial class SpeechBubbleControl : Control
{
private const string PartBubbleText = "BubbleText";
public static readonly DependencyProperty TextProperty = DependencyProperty.Register(nameof(Text), typeof(string), typeof(SpeechBubbleControl), new PropertyMetadata(""));
public SpeechBubbleControl()
{
DefaultStyleKey = typeof(SpeechBubbleControl);
}
public string Text
{
get { return GetValue(TextProperty).ToString(); }
set { SetValue(TextProperty, value); }
}
}
With its default template (SpeechBubbleControl.xaml):
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App6"
>
<Style TargetType="local:SpeechBubbleControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:SpeechBubbleControl">
<Grid Background="{TemplateBinding Background}" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Rectangle Fill="{TemplateBinding Background}" Stroke="#FF000000" RadiusX="10" RadiusY="10"/>
<Path Fill="{TemplateBinding Background}" Stretch="Fill" Stroke="#FF000000" HorizontalAlignment="Left" Margin="-15,-5,0,20" Width="30" Height="40" Data="M0,0 L15,40 30,20 0,0" RenderTransformOrigin="0.5,0.5" UseLayoutRounding="False">
<Path.RenderTransform>
<CompositeTransform Rotation="-20"/>
</Path.RenderTransform>
</Path>
<Rectangle Fill="{TemplateBinding Background}" RadiusX="10" RadiusY="10" Margin="1"/>
<TextBlock Name="BubbleText" HorizontalAlignment="Center" VerticalAlignment="Center"
Text="{TemplateBinding Text}" FontSize="20" TextWrapping="Wrap"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
You have to import this resource into your application resource using something like this in your app.xaml:
<Application
x:Class="App6.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App6"
RequestedTheme="Light">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="SpeechBubbleControl.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
And finally a sample test page, which use this control with bindings on width, height (based on the sliders) and the text that must be displayed.
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition />
</Grid.RowDefinitions>
<TextBox x:Name="testText" Grid.ColumnSpan="2" PlaceholderText="My text..." />
<Slider x:Name="width" Grid.Row="1" Minimum="50" Maximum="500" Value="200" />
<Slider x:Name="height" Grid.Row="1" Grid.Column="2" Minimum="50" Maximum="500" Value="100" />
<local:SpeechBubbleControl Grid.Row="2" Grid.ColumnSpan="2"
Width="{Binding Value, ElementName=width}"
Height="{Binding Value, ElementName=height}"
Text="{Binding Text, ElementName=testText, FallbackValue=Hello}"
Background="Beige" >
</local:SpeechBubbleControl>
</Grid>
<local:SpeechBubbleControl Grid.Row="2" Grid.ColumnSpan="2"
Width="{Binding Value, ElementName=width}" Height="{Binding Value, ElementName=height}"
Text="{Binding Text, ElementName=testText, FallbackValue=Hello}"
Background="Beige" >
</local:SpeechBubbleControl>
</Grid>
Here is the result:
Note that my answer is adapted from this one: WPF speech bubble

Related

Can't change Button Height WPF

I have a UserControl which contains a button CollapseConsoleBtn:
<UserControl //namespaces
<Grid
Name="LoggingGrid"
Height="100"
Background="Black">
<Grid.RowDefinitions>
<RowDefinition Height="25" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel
Grid.Row="0"
Margin="5,0,0,0"
Orientation="Horizontal">
<Button
x:Name="CollapseBtn"
Width="25"
Height="25"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Click="CollapseBtn_Click"
Content="▼"
FontSize="12">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Ellipse Fill="White" />
<ContentPresenter
HorizontalAlignment="Center"
VerticalAlignment="Center"
Content="{TemplateBinding Content}" />
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
<Image
Height="25"
Margin="7,0,0,0"
Source="/Images/console-icon.png"
Visibility="Visible" />
<Label
Margin="2,0,0,0"
Content="Console"
FontSize="16"
Foreground="White" />
</StackPanel>
</Grid>
</UserControl>
My problem here is that I want to make the button smaller - for example with Height 20 and Width 20. I can change the width, but apparently, the height is fixed to be 25. Even if I set it to 15, it remains the same size.
Has anyone encountered this problem?
I think trouble is in <TextBlock Grid.Row="0" Margin="{StaticResource SmallLeftMargin}"> (you put Button and StackPanel there).
I tried to removed it, a bit played with margins and paddings, setted a size of button 16x16 (MinWidth & MinHeight properties) and get this result:
UserControl XAML:
<Grid Name="LoggingGrid"
Height="100"
Background="Black">
<Grid.RowDefinitions>
<RowDefinition Height="26" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Button x:Name="CollapseButton"
Click="CollapseBtn_Click"
MinWidth="16"
MinHeight="16"
Margin="2,0,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Grid.Row="0"
Content="▼">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Ellipse Fill="White" />
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"
Content="{TemplateBinding Content}" />
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
<StackPanel Margin="5,0,0,0"
Orientation="Horizontal">
<Image Height="25"
Visibility="Visible" />
<Label Margin="18,0,0,0"
Content="Console"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
Padding="0,0,0,2"
FontSize="16"
Foreground="White" />
</StackPanel>
</Grid>
What you can do is:
Set the button's MinHeight instead of Height.
Make sure that the button's HorizontalAlignment and VerticalAlignment are set as their default value is Stretch.

Positioning texblocks in control template

Im trying to make exclamation mark next to the text for validation exception.
There is my custom template there is my XAML:
<Window x:Class="WpfApplicationLAB.NewGameWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplicationLAB"
mc:Ignorable="d"
Height="80" Width="260"
WindowStyle="None"
WindowStartupLocation="CenterScreen"
AllowsTransparency="False"
Title="NewGameWindow"
ResizeMode="CanResize" MinWidth="180" MinHeight="90">
<Grid Name="GridInputName">
<Grid.RowDefinitions>
<RowDefinition Height="25*"/>
<RowDefinition Height="29*"/>
<RowDefinition Height="28*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="51*"/>
<ColumnDefinition Width="121*"/>
</Grid.ColumnDefinitions>
<Label Grid.Row="1" Grid.Column="0" Content="Size:" HorizontalContentAlignment="Center"/>
<TextBox Name="textBox" Grid.Row="1" Grid.Column="1">
<TextBox.Text>
<Binding Path="Ssize" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<local:SizeValidation/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<Button Name="Cancel"
Grid.Row="2" Grid.Column="0" Content="Cancel" Click="Cancel_Click" >
</Button>
<Button Name="Ok"
Grid.Row="2" Grid.Column="1" Content="Ok" Click="Ok_Click">
</Button>
</Grid>
<Window.Resources>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<StackPanel>
<Border Background="Red" Margin="0,0,0,0" Width="20" Height="20" CornerRadius="10"
ToolTip="{Binding ElementName=customAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">
<TextBlock Text="!" VerticalAlignment="center" HorizontalAlignment="center" FontWeight="Bold" Foreground="white">
</TextBlock>
</Border>
<TextBlock
Margin="5,0,0,0"
Foreground="Red"
Text="{Binding ElementName=MyAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">
</TextBlock>
<Border BorderBrush="Red" BorderThickness="1" Margin="5,0,5,0" >
<AdornedElementPlaceholder Name="MyAdorner" ></AdornedElementPlaceholder>
</Border>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
</Window>
I want the exclamation mark on the left side of the text, I can't reach it anyway i try, with stack panel and it's orientation changed, dock panels etc.
With this code it looks that:
in some different variables it can be on the left side of the textbox
Any tips?
Try to wrap the Border with Background="Red" and the TextBlock with Foreground="Red" in a StackPanel with Orientation="Horizontal".
<Style TargetType="{x:Type TextBox}">
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<StackPanel>
<StackPanel Orientation="Horizontal">
<Border Background="Red"
Margin="0"
Width="20"
Height="20"
CornerRadius="10"
ToolTip="{Binding ElementName=customAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">
<TextBlock Text="!"
VerticalAlignment="center"
HorizontalAlignment="center"
FontWeight="Bold"
Foreground="white"/>
</Border>
<TextBlock Margin="5,0,0,0"
Foreground="Red"
Text="{Binding ElementName=MyAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}"/>
</StackPanel>
<Border BorderBrush="Red" BorderThickness="1" Margin="5,0" >
<AdornedElementPlaceholder Name="MyAdorner"/>
</Border>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
This worked for me.
PS: did you realize that you wrote MinHeight="90"... and then Height="80"? Does it make sense for you?

How to remove default chrome from a WPF ToggleButton

I have a ToggleButton defined like:
<ToggleButton Name="tbPinned" Grid.Row="0" Grid.Column="3" VerticalAlignment="Bottom" HorizontalAlignment="Left" Margin="1,0,0,-5" Height="30" Width="30" IsChecked="True" Checked="tbPinned_Checked" Unchecked="tbPinned_Unchecked" >
<Image Source="/some_image.png" Stretch="Fill" />
</ToggleButton>
However, I just want the button to be an image, not an image on a button. If I was using a normal Button I would just do something like Style="{DynamicResource NoChromeButton}" in the opening ToggleButton tag. But this does not work.
How can I mimic the whole NoChromeButton thing in a ToggleButton?
EDIT: Editted to include how I do it with regular Buttons:
<Button Style="{DynamicResource NoChromeButton}" Height="17" Margin="0,0,30,0" Name="btnMinimize" VerticalAlignment="Top" Grid.Column="1" Click="btnMinimize_Click" HorizontalAlignment="Right" Width="27" Padding="0" Visibility="Visible">
<Image Source="/some_image.png" Stretch="None" />
</Button>
Just copy/paste this into new WPF project.
<Window x:Class="SOChromeButton.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style x:Key="Chromeless" TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border BorderThickness="0" Width="54" Height="54">
<ContentPresenter/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<ToggleButton Style="{StaticResource Chromeless}" Name="tbPinned" Grid.Row="0" Grid.Column="0" VerticalAlignment="Bottom" HorizontalAlignment="Left" Margin="10,0,0,0" IsChecked="True" >
<Image Source="C:\Temp\info.png"></Image>
</ToggleButton>
</Grid> </Window>
Will this do?
<ToggleButton Name="tbPinned" Grid.Row="0" Grid.Column="3" VerticalAlignment="Bottom" HorizontalAlignment="Left" Margin="1,0,0,-5" Height="30" Width="30" IsChecked="True" Checked="tbPinned_Checked" Unchecked="tbPinned_Unchecked"
BorderThickness="0" Background="Transparent">
<Image Source="/some_image.png" Stretch="Fill" />
</ToggleButton>

How to Change Pivot Header Template in Windows Phone 8

I would like to be able to change the background of the Pivot Headers and Application Title in Windows Phone 8. From what I gather, I must create a custom style targeting the Pivot control. I am not sure, however, to change the background of only the headers?
I would like to adjust the style somehow
<Style x:Key="MyPivotStyle" TargetType="phone:Pivot">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="phone:Pivot">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid CacheMode="BitmapCache" Grid.RowSpan="2">
<Grid.Background>
<ImageBrush ImageSource="/Assets/bg_header.png"/>
</Grid.Background>
</Grid>
<Grid Background="{TemplateBinding Background}" CacheMode="BitmapCache" Grid.Row="2" />
<ContentPresenter ContentTemplate="{TemplateBinding TitleTemplate}" Margin="24,17,0,-7">
<StackPanel Orientation="Horizontal">
<Image Source="/Assets/company_name.png" Width="213.75" HorizontalAlignment="Left" VerticalAlignment="Top" />
<Button HorizontalAlignment="Right" VerticalAlignment="Top" Margin="140,-20,0,35" BorderThickness="0" x:Name="btnHome">
<Image Source="/Assets/btnHome.png" Width="48" Height="48" ></Image>
</Button>
</StackPanel>
</ContentPresenter>
<controlsPrimitives:PivotHeadersControl x:Name="HeadersListElement" Foreground="White" Grid.Row="1"/>
<ItemsPresenter x:Name="PivotItemPresenter" Margin="{TemplateBinding Padding}" Grid.Row="2"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
EDITED for WinRT (sorry for the delay and thanks for the reminder to update this answer):
To edit a full template right click on the control when in Document Outline and select Edit Template - Current (in Visual Studio or Blend) and the template will be generated for you and you can edit as you want, see my answer here for screenshots.
Here are the two examples below (posted in 2013) redone for Windows Phone Windows Runtime:
<Grid Background="Transparent">
<Pivot Title="Re-templating example">
<Pivot.HeaderTemplate>
<DataTemplate>
<Grid Background="Blue">
<TextBlock Text="{Binding}" />
</Grid>
</DataTemplate>
</Pivot.HeaderTemplate>
<Pivot.TitleTemplate>
<DataTemplate>
<Grid Background="Green">
<TextBlock Text="{Binding}" />
</Grid>
</DataTemplate>
</Pivot.TitleTemplate>
<PivotItem Header="One">
<TextBlock FontSize="35"
Text="This is item one" />
</PivotItem>
<PivotItem Header="Two">
<TextBlock FontSize="35"
Text="This is item 2" />
</PivotItem>
</Pivot>
</Grid>
And second example, notice that we are wrapping the ContentPresenter in a Grid (you could use a border as well or any other element):
<Page.Resources>
<SolidColorBrush x:Key="PivotBackground" Color="#FFE46C08"/>
<Style x:Key="PivotStyle" TargetType="Pivot">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Pivot">
<Grid x:Name="RootElement" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--Notice that ContentControl is wrapped in a Grid and Background set to resource furtehr up-->
<Grid VerticalAlignment="Center" Background="{StaticResource PivotBackground}">
<ContentControl x:Name="TitleContentControl" ContentTemplate="{TemplateBinding TitleTemplate}" Content="{TemplateBinding Title}" Style="{StaticResource PivotTitleContentControlStyle}"/>
</Grid>
<ScrollViewer x:Name="ScrollViewer" HorizontalSnapPointsAlignment="Center" HorizontalSnapPointsType="MandatorySingle" HorizontalScrollBarVisibility="Hidden" Margin="{TemplateBinding Padding}" Grid.Row="1" Template="{StaticResource ScrollViewerScrollBarlessTemplate}" VerticalSnapPointsType="None" VerticalScrollBarVisibility="Disabled" VerticalScrollMode="Disabled" VerticalContentAlignment="Stretch" ZoomMode="Disabled">
<PivotPanel x:Name="Panel" VerticalAlignment="Stretch">
<!--Background set to resource further up-->
<PivotHeaderPanel Background="{StaticResource PivotBackground}" x:Name="Header" >
<PivotHeaderPanel.RenderTransform>
<CompositeTransform x:Name="HeaderTranslateTransform" TranslateX="0"/>
</PivotHeaderPanel.RenderTransform>
</PivotHeaderPanel>
<ItemsPresenter x:Name="PivotItemPresenter">
<ItemsPresenter.RenderTransform>
<TranslateTransform x:Name="ItemsPresenterTranslateTransform" X="0"/>
</ItemsPresenter.RenderTransform>
</ItemsPresenter>
</PivotPanel>
</ScrollViewer>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
Using the above style:
<Grid Background="Transparent">
<Pivot Style="{StaticResource PivotStyle}"
Title="Re-templating example">
<PivotItem Header="One">
<TextBlock FontSize="35" Text="This is item one" />
</PivotItem>
<PivotItem Header="Two">
<TextBlock FontSize="35" Text="This is item 2"/>
</PivotItem>
</Pivot>
</Grid>
By the way, it's usually preferred to keep styles in a separate style file- I've only kept them on the same page for simplicity for this example. If you remove the x:key attribute the style will be applied to all the controls of the set target type (Pivot in this example).
Answer from 2013 for Windows Phone 7.X and Windows Phone 8 (WP Silverlight:
There are a few ways you can do it, but here is one example:
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<phone:Pivot Grid.Row="1">
<phone:Pivot.HeaderTemplate>
<DataTemplate>
<Grid Background="Red" Height="200">
<TextBlock Text="{Binding}"/>
</Grid>
</DataTemplate>
</phone:Pivot.HeaderTemplate>
<phone:PivotItem Header="Test">
<TextBlock Text="ghjgb"/>
</phone:PivotItem>
<phone:PivotItem Header="Test">
<TextBlock Text="ghjgb"/>
</phone:PivotItem>
</phone:Pivot>
If you however want to do this:
You can do this, remove the x:key to apply to all pivoits, or use the key to set the style on just selected pivoit elements like so:
<controls:Pivot Title="The Marathon Runner" Style="{StaticResource PivotStyle}">
<Style x:Key="PivotStyle" TargetType="phone:Pivot">
<Setter Property="Margin" Value="0"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<Grid/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="phone:Pivot">
<Grid HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
VerticalAlignment="{TemplateBinding VerticalAlignment}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Background="#ff9000" CacheMode="BitmapCache" Grid.RowSpan="2" />
<Grid Background="{TemplateBinding Background}" CacheMode="BitmapCache"
Grid.Row="2" />
<ContentPresenter ContentTemplate="{TemplateBinding TitleTemplate}"
Content="{TemplateBinding Title}" Margin="24,17,0,-7"/>
<Primitives:PivotHeadersControl x:Name="HeadersListElement"
Grid.Row="1"/>
<ItemsPresenter x:Name="PivotItemPresenter"
Margin="{TemplateBinding Padding}" Grid.Row="2"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
Dont forget to use:
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:Primitives="clr-namespace:Microsoft.Phone.Controls.Primitives;assembly=Microsoft.Phone"

Grid Border / Gap between cells

I've created a ControlTemplate that contains a Grid with two rows.
Sadly, there appears to be a single pixel gap between the cells.
How do I remove the gap?
Here's a screenshot showing the gap:
...and here's the XAML:
<Window x:Class="MAQButtonTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="695" Width="996">
<Window.Resources>
<Style TargetType="TextBlock">
<Setter Property="OverridesDefaultStyle" Value="True"/>
</Style>
<ControlTemplate TargetType="Button" x:Key="ButtonTemplate">
<Grid Width="444" Margin="0" ShowGridLines="False">
<Grid.RowDefinitions>
<RowDefinition Height="51" />
<RowDefinition Height="36" />
</Grid.RowDefinitions>
<Grid Grid.Row="0" Background="#286c97">
<TextBlock>This is the first piece of text</TextBlock>
</Grid>
<Grid Grid.Row="1" Background="#5898c0">
<ContentPresenter Grid.Row="0" />
</Grid>
</Grid>
</ControlTemplate>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" Background="#e9f1f6"></Grid>
<Grid Grid.Column="1" Background="#d2e3ed">
<StackPanel>
<TextBlock FontFamily="Segoe UI" FontSize="22" FontWeight="Medium" Margin="52,58,0,0" Foreground="#0c3d5d">Your Quizzes <TextBlock FontFamily="Segoe UI" FontSize="18" FontWeight="Medium" Foreground="#0c3d5d">(7)</TextBlock></TextBlock>
<Grid Margin="0,20,0,0">
<Button Width="444" Background="{x:Null}" BorderThickness="0" Template="{StaticResource ButtonTemplate}" Click="DoSomething" BorderBrush="#032135">
<TextBlock Margin="6,2.8,0,0" FontFamily="Segoe UI" FontSize="19" Foreground="#032135" FontWeight="Medium">This is a second piece of text</TextBlock>
</Button>
</Grid>
</StackPanel>
</Grid>
</Grid>
</Window>
Just add SnapsToDevicePixels="True" in your template grid
<ControlTemplate TargetType="Button" x:Key="ButtonTemplate">
<Grid Width="444" Margin="0" ShowGridLines="False" SnapsToDevicePixels="True">
<Grid.RowDefinitions>
<RowDefinition Height="51" />
<RowDefinition Height="36" />
</Grid.RowDefinitions>
<Grid Grid.Row="0" Background="#286c97">
<TextBlock>This is the first piece of text</TextBlock>
</Grid>
<Grid Grid.Row="1" Background="#5898c0">
<ContentPresenter Grid.Row="0" />
</Grid>
</Grid>
</ControlTemplate>
Set
SnapsToDevicePixels="True"
On grids in template or button, but better just create new style with SnapsToDevicePixels="True" setter and template inside style.

Categories