WPF C#/VB
Shapes: Part 2 (Lines, Outlines & Exporting Shapes)
C#
// AZUL CODING ---------------------------------------
// WPF C#/VB - Shapes: Part 2 (Lines, Outlines & Exporting Shapes)
// https://youtu.be/efHcwDmzpjs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Drawing;
namespace Shapes
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private string CurrentShape = "Rectangle";
public MainWindow()
{
InitializeComponent();
}
private void ShapeRadios_Click(object sender, RoutedEventArgs e)
{
RectangleShape.Visibility = Visibility.Collapsed;
EllipseShape.Visibility = Visibility.Collapsed;
TriangleShape.Visibility = Visibility.Collapsed;
LineShape.Visibility = Visibility.Collapsed;
HeightLbl.Visibility = Visibility.Visible;
HeightSlider.Visibility = Visibility.Visible;
FillColourLbl.Visibility = Visibility.Visible;
FillColourPicker.Visibility = Visibility.Visible;
switch (((RadioButton)sender).Name)
{
case "RectangleRadio":
RectangleShape.Visibility = Visibility.Visible;
CurrentShape = "Rectangle";
break;
case "EllipseRadio":
EllipseShape.Visibility = Visibility.Visible;
CurrentShape = "Ellipse";
break;
case "TriangleRadio":
TriangleShape.Visibility = Visibility.Visible;
CurrentShape = "Triangle";
break;
case "LineRadio":
LineShape.Visibility = Visibility.Visible;
HeightLbl.Visibility = Visibility.Collapsed;
HeightSlider.Visibility = Visibility.Collapsed;
FillColourLbl.Visibility = Visibility.Collapsed;
FillColourPicker.Visibility = Visibility.Collapsed;
CurrentShape = "Line";
break;
default:
break;
}
}
private void WidthSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
RectangleShape.Width = WidthSlider.Value * 25;
EllipseShape.Width = WidthSlider.Value * 25;
// 100,0
// △
// 0,200 200,200
List<double> shapepoints = new List<double>() { };
PointCollection newpoints = new PointCollection();
foreach (System.Windows.Point pt in TriangleShape.Points)
{
shapepoints.Add(pt.X);
}
shapepoints = shapepoints.Distinct().ToList();
foreach (System.Windows.Point pt in TriangleShape.Points)
{
if (pt.X == shapepoints.Max())
{
newpoints.Add(new System.Windows.Point(WidthSlider.Value * 25, pt.Y));
}
else if (pt.X != shapepoints.Min())
{
newpoints.Add(new System.Windows.Point(WidthSlider.Value * 25 / 2, pt.Y));
}
else
{
newpoints.Add(new System.Windows.Point(pt.X, pt.Y));
}
}
TriangleShape.Points = newpoints;
LineShape.X2 = WidthSlider.Value * 25;
}
private void HeightSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
RectangleShape.Height = HeightSlider.Value * 25;
EllipseShape.Height = HeightSlider.Value * 25;
List<double> shapepoints = new List<double>() { };
PointCollection newpoints = new PointCollection();
foreach (System.Windows.Point pt in TriangleShape.Points)
{
shapepoints.Add(pt.Y);
}
shapepoints = shapepoints.Distinct().ToList();
foreach (System.Windows.Point pt in TriangleShape.Points)
{
if (pt.Y == shapepoints.Max())
{
newpoints.Add(new System.Windows.Point(pt.X, HeightSlider.Value * 25));
}
else if (pt.Y != shapepoints.Min())
{
newpoints.Add(new System.Windows.Point(pt.X, HeightSlider.Value * 25 / 2));
}
else
{
newpoints.Add(new System.Windows.Point(pt.X, pt.Y));
}
}
TriangleShape.Points = newpoints;
}
private void FillColourPicker_SelectedColorChanged(object sender, RoutedPropertyChangedEventArgs<System.Windows.Media.Color?> e)
{
SolidColorBrush clr = new SolidColorBrush((System.Windows.Media.Color)FillColourPicker.SelectedColor);
RectangleShape.Fill = clr;
EllipseShape.Fill = clr;
TriangleShape.Fill = clr;
}
private void LineColourPicker_SelectedColorChanged(object sender, RoutedPropertyChangedEventArgs<System.Windows.Media.Color?> e)
{
SolidColorBrush clr = new SolidColorBrush((System.Windows.Media.Color)LineColourPicker.SelectedColor);
RectangleShape.Stroke = clr;
EllipseShape.Stroke = clr;
TriangleShape.Stroke = clr;
LineShape.Stroke = clr;
}
private void ThicknessSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
RectangleShape.StrokeThickness = ThicknessSlider.Value;
EllipseShape.StrokeThickness = ThicknessSlider.Value;
TriangleShape.StrokeThickness = ThicknessSlider.Value;
LineShape.StrokeThickness = ThicknessSlider.Value;
}
private void LineEffectRadios_Click(object sender, RoutedEventArgs e)
{
DoubleCollection arr = new DoubleCollection() { 1, 0 };
if (DashedRadio.IsChecked == true)
{
arr = new DoubleCollection() { 4, 4 };
}
else if (DottedRadio.IsChecked == true)
{
arr = new DoubleCollection() { 2, 2 };
}
RectangleShape.StrokeDashArray = arr;
EllipseShape.StrokeDashArray = arr;
TriangleShape.StrokeDashArray = arr;
LineShape.StrokeDashArray = arr;
}
private void ExportBtn_Click(object sender, RoutedEventArgs e)
{
int bmpheight, bmpwidth, r, g, b, thickness;
Bitmap bmp = new Bitmap(1, 1);
SolidBrush fill, outline;
System.Drawing.Pen pen;
System.Drawing.Rectangle rect;
r = FillColourPicker.SelectedColor.Value.R;
g = FillColourPicker.SelectedColor.Value.G;
b = FillColourPicker.SelectedColor.Value.B;
fill = new SolidBrush(System.Drawing.Color.FromArgb(r, g, b));
r = LineColourPicker.SelectedColor.Value.R;
g = LineColourPicker.SelectedColor.Value.G;
b = LineColourPicker.SelectedColor.Value.B;
outline = new SolidBrush(System.Drawing.Color.FromArgb(r, g, b));
thickness = (int)ThicknessSlider.Value * 2;
pen = new System.Drawing.Pen(outline)
{
Width = thickness
};
if (DashedRadio.IsChecked == true)
{
pen.DashPattern = new float[] { 2f, 2f };
}
else if (DottedRadio.IsChecked == true)
{
pen.DashPattern = new float[] { 1f, 1f };
}
switch (CurrentShape)
{
case "Rectangle":
bmpheight = (int)RectangleShape.ActualHeight;
bmpwidth = (int)RectangleShape.ActualWidth;
rect = new System.Drawing.Rectangle(thickness / 2, thickness / 2, bmpwidth - thickness, bmpheight - thickness);
bmp = new Bitmap(bmpwidth, bmpheight);
using (Graphics gr = Graphics.FromImage(bmp))
{
gr.DrawRectangle(pen, rect);
gr.FillRectangle(fill, rect);
}
break;
case "Ellipse":
bmpheight = (int)EllipseShape.ActualHeight;
bmpwidth = (int)EllipseShape.ActualWidth;
rect = new System.Drawing.Rectangle(thickness / 2, thickness / 2, bmpwidth - thickness, bmpheight - thickness);
bmp = new Bitmap(bmpwidth, bmpheight);
using (Graphics gr = Graphics.FromImage(bmp))
{
gr.DrawEllipse(pen, rect);
gr.FillEllipse(fill, rect);
}
break;
case "Triangle":
bmpheight = (int)TriangleShape.ActualHeight;
bmpwidth = (int)TriangleShape.ActualWidth;
bmp = new Bitmap(bmpwidth, bmpheight);
List<double> xpoints = new List<double>() { };
List<double> ypoints = new List<double>() { };
List<System.Drawing.Point> newpoints = new List<System.Drawing.Point>();
foreach (System.Windows.Point pt in TriangleShape.Points)
{
xpoints.Add(pt.X);
ypoints.Add(pt.Y);
}
xpoints = xpoints.Distinct().ToList();
ypoints = ypoints.Distinct().ToList();
int counter = 0;
foreach (System.Windows.Point pt in TriangleShape.Points)
{
if (pt.X == xpoints.Max())
{
newpoints.Add(new System.Drawing.Point((int)pt.X - thickness, (int)pt.Y));
}
else if (pt.X == xpoints.Min())
{
newpoints.Add(new System.Drawing.Point((int)pt.X + thickness, (int)pt.Y));
}
else
{
newpoints.Add(new System.Drawing.Point((int)pt.X, (int)pt.Y));
}
if (pt.Y == ypoints.Max())
{
newpoints[counter] = new System.Drawing.Point(newpoints[counter].X, (int)pt.Y - (thickness / 2));
}
else if (pt.Y == ypoints.Min())
{
newpoints[counter] = new System.Drawing.Point(newpoints[counter].X, (int)pt.Y + thickness);
}
counter++;
}
using (Graphics gr = Graphics.FromImage(bmp))
{
gr.DrawPolygon(pen, newpoints.ToArray());
gr.FillPolygon(fill, newpoints.ToArray());
}
break;
case "Line":
bmpwidth = (int)LineShape.ActualWidth;
bmpheight = (int)LineShape.StrokeThickness;
bmp = new Bitmap(bmpwidth, bmpheight);
using (Graphics gr = Graphics.FromImage(bmp))
{
gr.DrawLine(pen, (int)LineShape.X1, (int)LineShape.Y1, (int)LineShape.X2, (int)LineShape.Y2);
}
break;
default:
break;
}
pen.Dispose();
fill.Dispose();
outline.Dispose();
bmp.Save(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures) + "\\shape.png");
MessageBox.Show("Shape exported as image.");
}
}
}
VB.NET
' AZUL CODING ---------------------------------------
' WPF C#/VB - Shapes: Part 2 (Lines, Outlines & Exporting Shapes)
' https://youtu.be/efHcwDmzpjs
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Media
Imports System.Drawing
Class MainWindow
Private CurrentShape As String = "Rectangle"
Public Sub New()
InitializeComponent()
End Sub
Private Sub ShapeRadios_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
RectangleShape.Visibility = Visibility.Collapsed
EllipseShape.Visibility = Visibility.Collapsed
TriangleShape.Visibility = Visibility.Collapsed
LineShape.Visibility = Visibility.Collapsed
HeightLbl.Visibility = Visibility.Visible
HeightSlider.Visibility = Visibility.Visible
FillColourLbl.Visibility = Visibility.Visible
FillColourPicker.Visibility = Visibility.Visible
Select Case (CType(sender, RadioButton)).Name
Case "RectangleRadio"
RectangleShape.Visibility = Visibility.Visible
CurrentShape = "Rectangle"
Case "EllipseRadio"
EllipseShape.Visibility = Visibility.Visible
CurrentShape = "Ellipse"
Case "TriangleRadio"
TriangleShape.Visibility = Visibility.Visible
CurrentShape = "Triangle"
Case "LineRadio"
LineShape.Visibility = Visibility.Visible
HeightLbl.Visibility = Visibility.Collapsed
HeightSlider.Visibility = Visibility.Collapsed
FillColourLbl.Visibility = Visibility.Collapsed
FillColourPicker.Visibility = Visibility.Collapsed
CurrentShape = "Line"
Case Else
End Select
End Sub
Private Sub WidthSlider_ValueChanged(ByVal sender As Object, ByVal e As RoutedPropertyChangedEventArgs(Of Double))
RectangleShape.Width = WidthSlider.Value * 25
EllipseShape.Width = WidthSlider.Value * 25
' 100,0
' △
' 0,200 200,200
Dim shapepoints As List(Of Double) = New List(Of Double) From {}
Dim newpoints As PointCollection = New PointCollection()
For Each pt As System.Windows.Point In TriangleShape.Points
shapepoints.Add(pt.X)
Next
shapepoints = shapepoints.Distinct().ToList()
For Each pt As System.Windows.Point In TriangleShape.Points
If pt.X = shapepoints.Max() Then
newpoints.Add(New System.Windows.Point(WidthSlider.Value * 25, pt.Y))
ElseIf pt.X <> shapepoints.Min() Then
newpoints.Add(New System.Windows.Point(WidthSlider.Value * 25 / 2, pt.Y))
Else
newpoints.Add(New System.Windows.Point(pt.X, pt.Y))
End If
Next
TriangleShape.Points = newpoints
LineShape.X2 = WidthSlider.Value * 25
End Sub
Private Sub HeightSlider_ValueChanged(ByVal sender As Object, ByVal e As RoutedPropertyChangedEventArgs(Of Double))
RectangleShape.Height = HeightSlider.Value * 25
EllipseShape.Height = HeightSlider.Value * 25
Dim shapepoints As List(Of Double) = New List(Of Double) From {}
Dim newpoints As PointCollection = New PointCollection()
For Each pt As System.Windows.Point In TriangleShape.Points
shapepoints.Add(pt.Y)
Next
shapepoints = shapepoints.Distinct().ToList()
For Each pt As System.Windows.Point In TriangleShape.Points
If pt.Y = shapepoints.Max() Then
newpoints.Add(New System.Windows.Point(pt.X, HeightSlider.Value * 25))
ElseIf pt.Y <> shapepoints.Min() Then
newpoints.Add(New System.Windows.Point(pt.X, HeightSlider.Value * 25 / 2))
Else
newpoints.Add(New System.Windows.Point(pt.X, pt.Y))
End If
Next
TriangleShape.Points = newpoints
End Sub
Private Sub FillColourPicker_SelectedColorChanged(ByVal sender As Object, ByVal e As RoutedPropertyChangedEventArgs(Of System.Windows.Media.Color))
Dim clr As SolidColorBrush = New SolidColorBrush(CType(FillColourPicker.SelectedColor, System.Windows.Media.Color))
RectangleShape.Fill = clr
EllipseShape.Fill = clr
TriangleShape.Fill = clr
End Sub
Private Sub LineColourPicker_SelectedColorChanged(ByVal sender As Object, ByVal e As RoutedPropertyChangedEventArgs(Of System.Windows.Media.Color))
Dim clr As SolidColorBrush = New SolidColorBrush(CType(LineColourPicker.SelectedColor, System.Windows.Media.Color))
RectangleShape.Stroke = clr
EllipseShape.Stroke = clr
TriangleShape.Stroke = clr
LineShape.Stroke = clr
End Sub
Private Sub ThicknessSlider_ValueChanged(ByVal sender As Object, ByVal e As RoutedPropertyChangedEventArgs(Of Double))
RectangleShape.StrokeThickness = ThicknessSlider.Value
EllipseShape.StrokeThickness = ThicknessSlider.Value
TriangleShape.StrokeThickness = ThicknessSlider.Value
LineShape.StrokeThickness = ThicknessSlider.Value
End Sub
Private Sub LineEffectRadios_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
Dim arr As DoubleCollection = New DoubleCollection() From { 1, 0 }
If DashedRadio.IsChecked = True Then
arr = New DoubleCollection() From { 4, 4 }
ElseIf DottedRadio.IsChecked = True Then
arr = New DoubleCollection() From { 2, 2 }
End If
RectangleShape.StrokeDashArray = arr
EllipseShape.StrokeDashArray = arr
TriangleShape.StrokeDashArray = arr
LineShape.StrokeDashArray = arr
End Sub
Private Sub ExportBtn_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
Dim bmpheight, bmpwidth, r, g, b, thickness As Integer
Dim bmp As Bitmap = New Bitmap(1, 1)
Dim fill, outline As SolidBrush
Dim pen As System.Drawing.Pen
Dim rect As System.Drawing.Rectangle
r = FillColourPicker.SelectedColor.Value.R
g = FillColourPicker.SelectedColor.Value.G
b = FillColourPicker.SelectedColor.Value.B
fill = New SolidBrush(System.Drawing.Color.FromArgb(r, g, b))
r = LineColourPicker.SelectedColor.Value.R
g = LineColourPicker.SelectedColor.Value.G
b = LineColourPicker.SelectedColor.Value.B
outline = New SolidBrush(System.Drawing.Color.FromArgb(r, g, b))
thickness = CInt(ThicknessSlider.Value) * 2
pen = New System.Drawing.Pen(outline) With {
.Width = thickness
}
If DashedRadio.IsChecked = True Then
pen.DashPattern = New Single() {2F, 2F}
ElseIf DottedRadio.IsChecked = True Then
pen.DashPattern = New Single() {1F, 1F}
End If
Select Case CurrentShape
Case "Rectangle"
bmpheight = CInt(RectangleShape.ActualHeight)
bmpwidth = CInt(RectangleShape.ActualWidth)
rect = New System.Drawing.Rectangle(thickness / 2, thickness / 2, bmpwidth - thickness, bmpheight - thickness)
bmp = New Bitmap(bmpwidth, bmpheight)
Using gr As Graphics = Graphics.FromImage(bmp)
gr.DrawRectangle(pen, rect)
gr.FillRectangle(fill, rect)
End Using
Case "Ellipse"
bmpheight = CInt(EllipseShape.ActualHeight)
bmpwidth = CInt(EllipseShape.ActualWidth)
rect = New System.Drawing.Rectangle(thickness / 2, thickness / 2, bmpwidth - thickness, bmpheight - thickness)
bmp = New Bitmap(bmpwidth, bmpheight)
Using gr As Graphics = Graphics.FromImage(bmp)
gr.DrawEllipse(pen, rect)
gr.FillEllipse(fill, rect)
End Using
Case "Triangle"
bmpheight = CInt(TriangleShape.ActualHeight)
bmpwidth = CInt(TriangleShape.ActualWidth)
bmp = New Bitmap(bmpwidth, bmpheight)
Dim xpoints As List(Of Double) = New List(Of Double) From {}
Dim ypoints As List(Of Double) = New List(Of Double) From {}
Dim newpoints As List(Of System.Drawing.Point) = New List(Of System.Drawing.Point)()
For Each pt As System.Windows.Point In TriangleShape.Points
xpoints.Add(pt.X)
ypoints.Add(pt.Y)
Next
xpoints = xpoints.Distinct().ToList()
ypoints = ypoints.Distinct().ToList()
Dim counter As Integer = 0
For Each pt As System.Windows.Point In TriangleShape.Points
If pt.X = xpoints.Max() Then
newpoints.Add(New System.Drawing.Point(CInt(pt.X) - thickness, CInt(pt.Y)))
ElseIf pt.X = xpoints.Min() Then
newpoints.Add(New System.Drawing.Point(CInt(pt.X) + thickness, CInt(pt.Y)))
Else
newpoints.Add(New System.Drawing.Point(CInt(pt.X), CInt(pt.Y)))
End If
If pt.Y = ypoints.Max() Then
newpoints(counter) = New System.Drawing.Point(newpoints(counter).X, CInt(pt.Y) - (thickness / 2))
ElseIf pt.Y = ypoints.Min() Then
newpoints(counter) = New System.Drawing.Point(newpoints(counter).X, CInt(pt.Y) + thickness)
End If
counter += 1
Next
Using gr As Graphics = Graphics.FromImage(bmp)
gr.DrawPolygon(pen, newpoints.ToArray())
gr.FillPolygon(fill, newpoints.ToArray())
End Using
Case "Line"
bmpwidth = CInt(LineShape.ActualWidth)
bmpheight = CInt(LineShape.StrokeThickness)
bmp = New Bitmap(bmpwidth, bmpheight)
Using gr As Graphics = Graphics.FromImage(bmp)
gr.DrawLine(pen, CInt(LineShape.X1), CInt(LineShape.Y1), CInt(LineShape.X2), CInt(LineShape.Y2))
End Using
Case Else
End Select
pen.Dispose()
fill.Dispose()
outline.Dispose()
bmp.Save(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures) & "\shape.png")
MessageBox.Show("Shape exported as image.")
End Sub
End Class
XAML
<!-- AZUL CODING --------------------------------------- -->
<!-- WPF C#/VB - Shapes: Part 2 (Lines, Outlines & Exporting Shapes) -->
<!-- https://youtu.be/efHcwDmzpjs -->
<Window x:Class="Shapes.MainWindow"
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:Shapes" xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
mc:Ignorable="d"
Title="Shapes - Azul Coding" Width="875" MinHeight="475" ResizeMode="CanMinimize" SizeToContent="Height">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="500"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid Margin="20,20,0,20" Grid.Column="0">
<Rectangle x:Name="RectangleShape" HorizontalAlignment="Center" VerticalAlignment="Center" Width="200" Height="200" Fill="#108beb" Stroke="#0c3c62" StrokeThickness="2"/>
<Ellipse x:Name="EllipseShape" HorizontalAlignment="Center" VerticalAlignment="Center" Width="200" Height="200" Fill="#108beb" Stroke="#0c3c62" StrokeThickness="2" Visibility="Collapsed"/>
<Polygon x:Name="TriangleShape" HorizontalAlignment="Center" VerticalAlignment="Center" Points="0,200 100,0 200,200" Fill="#108beb" Stroke="#0c3c62" StrokeThickness="2" Visibility="Collapsed"/>
<Line x:Name="LineShape" HorizontalAlignment="Center" VerticalAlignment="Center" Stroke="#0c3c62" StrokeThickness="2" X1="0" X2="200" Visibility="Collapsed"/>
</Grid>
<StackPanel Grid.Column="1" Margin="20">
<Label x:Name="ShapeLbl" Content="Choose a shape" FontSize="14"/>
<StackPanel Orientation="Horizontal">
<RadioButton Name="RectangleRadio" Content="Rectangle" GroupName="ShapeRadios" Margin="10,5,0,0" IsChecked="True" Click="ShapeRadios_Click"/>
<RadioButton Name="EllipseRadio" Content="Ellipse" GroupName="ShapeRadios" Margin="20,5,0,0" Click="ShapeRadios_Click"/>
<RadioButton Name="TriangleRadio" Content="Triangle" GroupName="ShapeRadios" Margin="20,5,0,0" Click="ShapeRadios_Click"/>
<RadioButton Name="LineRadio" Content="Line" GroupName="ShapeRadios" Margin="20,5,0,0" Click="ShapeRadios_Click"/>
</StackPanel>
<Label x:Name="WidthLbl" Content="Width" FontSize="14" Margin="0,20,0,0"/>
<Slider x:Name="WidthSlider" Orientation="Horizontal" Margin="10,5,10,0" Value="8" IsSnapToTickEnabled="True" Minimum="1" Maximum="16" ValueChanged="WidthSlider_ValueChanged"/>
<Label x:Name="HeightLbl" Content="Height" FontSize="14" Margin="0,20,0,0"/>
<Slider x:Name="HeightSlider" Orientation="Horizontal" Margin="10,5,10,0" Value="8" IsSnapToTickEnabled="True" Minimum="1" Maximum="16" ValueChanged="HeightSlider_ValueChanged"/>
<Label x:Name="FillColourLbl" Content="Fill colour" FontSize="14" Margin="0,20,0,0"/>
<xctk:ColorPicker x:Name="FillColourPicker" Height="26" ColorMode="ColorCanvas" UsingAlphaChannel="False" Margin="10,5,10,0" SelectedColor="#108beb" SelectedColorChanged="FillColourPicker_SelectedColorChanged"/>
<Label x:Name="LineColourLbl" Content="Line colour" FontSize="14" Margin="0,20,0,0" Visibility="Visible"/>
<xctk:ColorPicker x:Name="LineColourPicker" Height="26" ColorMode="ColorCanvas" UsingAlphaChannel="False" Margin="10,5,10,0" SelectedColor="#0c3c62" SelectedColorChanged="LineColourPicker_SelectedColorChanged" Visibility="Visible"/>
<Label x:Name="ThicknessLbl" Content="Line thickness" FontSize="14" Margin="0,20,0,0" Visibility="Visible"/>
<Slider x:Name="ThicknessSlider" Orientation="Horizontal" Margin="10,5,10,0" Value="2" IsSnapToTickEnabled="True" Minimum="1" Maximum="5" ValueChanged="ThicknessSlider_ValueChanged" Visibility="Visible"/>
<Label x:Name="DashLbl" Content="Line effects" FontSize="14" Margin="0,20,0,0" Visibility="Visible"/>
<StackPanel Orientation="Horizontal" Visibility="Visible">
<RadioButton Name="NoEffectRadio" Content="None" GroupName="LineEffectRadios" Margin="10,5,0,0" IsChecked="True" Click="LineEffectRadios_Click"/>
<RadioButton Name="DashedRadio" Content="Dashes" GroupName="LineEffectRadios" Margin="20,5,0,0" Click="LineEffectRadios_Click"/>
<RadioButton Name="DottedRadio" Content="Dots" GroupName="LineEffectRadios" Margin="20,5,0,0" Click="LineEffectRadios_Click"/>
</StackPanel>
<Button Name="ExportBtn" Content="Export image" HorizontalAlignment="Right" Padding="15,5" Margin="10,25,10,0" Click="ExportBtn_Click" Visibility="Visible"/>
</StackPanel>
</Grid>
</Window>