WPF C#/VB.NET
Make Your Own Paint App
C#
// AZUL CODING ---------------------------------------
// WPF C#/VB.NET - Make Your Own Paint App
// https://youtu.be/0LEkcmD3w9w
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Ink;
namespace AzulPaint
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private readonly DrawingAttributes PenAttributes = new()
{
Color = Colors.Black,
Height = 2,
Width = 2
};
private readonly DrawingAttributes HighlighterAttributes = new()
{
Color = Colors.Yellow,
Height = 10,
Width = 2,
IgnorePressure = true,
IsHighlighter = true,
StylusTip = StylusTip.Rectangle
};
public MainWindow()
{
InitializeComponent();
Canvas.DefaultDrawingAttributes = PenAttributes;
}
#region Editing Mode
private void SelectBtn_Click(object sender, RoutedEventArgs e)
{
SetEditingMode(EditingMode.Select);
}
private void PenBtn_Click(object sender, RoutedEventArgs e)
{
SetEditingMode(EditingMode.Pen);
}
private void HighlighterBtn_Click(object sender, RoutedEventArgs e)
{
SetEditingMode(EditingMode.Highlighter);
}
private void EraserBtn_Click(object sender, RoutedEventArgs e)
{
SetEditingMode(EditingMode.Eraser);
}
private void SetEditingMode(EditingMode mode)
{
SelectBtn.IsChecked = false;
PenBtn.IsChecked = false;
HighlighterBtn.IsChecked = false;
EraserBtn.IsChecked = false;
switch (mode)
{
case EditingMode.Select:
SelectBtn.IsChecked = true;
Canvas.EditingMode = InkCanvasEditingMode.Select;
break;
case EditingMode.Pen:
PenBtn.IsChecked = true;
Canvas.EditingMode = InkCanvasEditingMode.Ink;
Canvas.DefaultDrawingAttributes = PenAttributes;
break;
case EditingMode.Highlighter:
HighlighterBtn.IsChecked = true;
Canvas.EditingMode = InkCanvasEditingMode.Ink;
Canvas.DefaultDrawingAttributes = HighlighterAttributes;
break;
case EditingMode.Eraser:
EraserBtn.IsChecked = true;
if (PartialStrokeRadio.IsChecked == true)
Canvas.EditingMode = InkCanvasEditingMode.EraseByPoint;
else
Canvas.EditingMode = InkCanvasEditingMode.EraseByStroke;
break;
default:
break;
}
}
#endregion
#region Pen
private void PenColorPicker_SelectedColorChanged(object sender, RoutedPropertyChangedEventArgs<Color?> e)
{
if (IsLoaded)
PenAttributes.Color = PenColorPicker.SelectedColor ?? Colors.Black;
}
private void ThicknessSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
if (IsLoaded)
{
PenAttributes.Width = ThicknessSlider.Value;
PenAttributes.Height = ThicknessSlider.Value;
}
}
#endregion
#region Highlighter
private void YellowRadio_Click(object sender, RoutedEventArgs e)
{
HighlighterAttributes.Color = Colors.Yellow;
}
private void CyanRadio_Click(object sender, RoutedEventArgs e)
{
HighlighterAttributes.Color = Colors.Cyan;
}
private void MagentaRadio_Click(object sender, RoutedEventArgs e)
{
HighlighterAttributes.Color = Colors.Magenta;
}
#endregion
#region Eraser Type
private void PartialStrokeRadio_Click(object sender, RoutedEventArgs e)
{
if (EraserBtn.IsChecked == true)
Canvas.EditingMode = InkCanvasEditingMode.EraseByPoint;
}
private void FullStrokeRadio_Click(object sender, RoutedEventArgs e)
{
if (EraserBtn.IsChecked == true)
Canvas.EditingMode = InkCanvasEditingMode.EraseByStroke;
}
#endregion
}
public enum EditingMode
{
Select, Pen, Highlighter, Eraser
}
}
VB.NET
' AZUL CODING ---------------------------------------
' WPF C#/VB.NET - Make Your Own Paint App
' https://youtu.be/0LEkcmD3w9w
Imports System
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Media
Imports System.Windows.Ink
Class MainWindow
Private ReadOnly PenAttributes As DrawingAttributes = New DrawingAttributes() With {
.Color = Colors.Black,
.Height = 2,
.Width = 2
}
Private ReadOnly HighlighterAttributes As DrawingAttributes = New DrawingAttributes() With {
.Color = Colors.Yellow,
.Height = 10,
.Width = 2,
.IgnorePressure = True,
.IsHighlighter = True,
.StylusTip = StylusTip.Rectangle
}
Public Sub New()
InitializeComponent()
Canvas.DefaultDrawingAttributes = PenAttributes
End Sub
Private Sub SelectBtn_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
SetEditingMode(EditingMode.[Select])
End Sub
Private Sub PenBtn_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
SetEditingMode(EditingMode.Pen)
End Sub
Private Sub HighlighterBtn_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
SetEditingMode(EditingMode.Highlighter)
End Sub
Private Sub EraserBtn_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
SetEditingMode(EditingMode.Eraser)
End Sub
Private Sub SetEditingMode(ByVal mode As EditingMode)
SelectBtn.IsChecked = False
PenBtn.IsChecked = False
HighlighterBtn.IsChecked = False
EraserBtn.IsChecked = False
Select Case mode
Case EditingMode.[Select]
SelectBtn.IsChecked = True
Canvas.EditingMode = InkCanvasEditingMode.[Select]
Case EditingMode.Pen
PenBtn.IsChecked = True
Canvas.EditingMode = InkCanvasEditingMode.Ink
Canvas.DefaultDrawingAttributes = PenAttributes
Case EditingMode.Highlighter
HighlighterBtn.IsChecked = True
Canvas.EditingMode = InkCanvasEditingMode.Ink
Canvas.DefaultDrawingAttributes = HighlighterAttributes
Case EditingMode.Eraser
EraserBtn.IsChecked = True
If PartialStrokeRadio.IsChecked = True Then
Canvas.EditingMode = InkCanvasEditingMode.EraseByPoint
Else
Canvas.EditingMode = InkCanvasEditingMode.EraseByStroke
End If
Case Else
End Select
End Sub
Private Sub PenColorPicker_SelectedColorChanged(ByVal sender As Object, ByVal e As RoutedPropertyChangedEventArgs(Of Color?))
If IsLoaded Then PenAttributes.Color = If(PenColorPicker.SelectedColor, Colors.Black)
End Sub
Private Sub ThicknessSlider_ValueChanged(ByVal sender As Object, ByVal e As RoutedPropertyChangedEventArgs(Of Double))
If IsLoaded Then
PenAttributes.Width = ThicknessSlider.Value
PenAttributes.Height = ThicknessSlider.Value
End If
End Sub
Private Sub YellowRadio_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
HighlighterAttributes.Color = Colors.Yellow
End Sub
Private Sub CyanRadio_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
HighlighterAttributes.Color = Colors.Cyan
End Sub
Private Sub MagentaRadio_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
HighlighterAttributes.Color = Colors.Magenta
End Sub
Private Sub PartialStrokeRadio_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
If EraserBtn.IsChecked = True Then Canvas.EditingMode = InkCanvasEditingMode.EraseByPoint
End Sub
Private Sub FullStrokeRadio_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
If EraserBtn.IsChecked = True Then Canvas.EditingMode = InkCanvasEditingMode.EraseByStroke
End Sub
End Class
Public Enum EditingMode
[Select]
Pen
Highlighter
Eraser
End Enum
XAML
<!-- AZUL CODING --------------------------------------- -->
<!-- WPF C#/VB.NET - Make Your Own Paint App -->
<!-- https://youtu.be/0LEkcmD3w9w -->
<Window x:Class="AzulPaint.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:AzulPaint"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
mc:Ignorable="d"
Title="Paint App - Azul Coding" Height="550" Width="900" ResizeMode="CanMinimize">
<Grid Background="AliceBlue">
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="575"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Border Margin="20,20,0,20" BorderThickness="0,0,2,0" BorderBrush="DodgerBlue" Grid.Column="0">
<Grid Margin="20,20,40,20">
<Grid.Effect>
<DropShadowEffect Color="Black" BlurRadius="15" Opacity="0.15" ShadowDepth="2"/>
</Grid.Effect>
<InkCanvas x:Name="Canvas" Background="White"/>
</Grid>
</Border>
<StackPanel Grid.Column="1" Margin="20" VerticalAlignment="Center">
<Label Content="Editing mode" FontWeight="SemiBold" FontSize="16"/>
<StackPanel Orientation="Horizontal" Margin="5,10,0,0">
<ToggleButton Name="SelectBtn" Padding="5" Margin="0,0,10,0" ToolTip="Select" Background="White" Click="SelectBtn_Click">
<Image Height="24" Width="24" Source="https://img.icons8.com/fluency/48/cursor--v1.png"/>
</ToggleButton>
<ToggleButton Name="PenBtn" Padding="5" Margin="0,0,10,0" ToolTip="Pen" Background="White" IsChecked="True" Click="PenBtn_Click">
<Image Height="24" Width="24" Source="https://img.icons8.com/fluency/48/pen-1.png"/>
</ToggleButton>
<ToggleButton Name="HighlighterBtn" Padding="5" Margin="0,0,10,0" ToolTip="Highlighter" Background="White" Click="HighlighterBtn_Click">
<Image Height="24" Width="24" Source="https://img.icons8.com/fluency/48/border-color.png"/>
</ToggleButton>
<ToggleButton Name="EraserBtn" Padding="5" Margin="0,0,10,0" ToolTip="Eraser" Background="White" Click="EraserBtn_Click">
<Image Height="24" Width="24" Source="https://img.icons8.com/fluency/48/erase.png"/>
</ToggleButton>
</StackPanel>
<Label Content="Pen colour" FontWeight="SemiBold" FontSize="16" Margin="0,25,0,0"/>
<xctk:ColorPicker x:Name="PenColorPicker" SelectedColorChanged="PenColorPicker_SelectedColorChanged" ShowStandardColors="False" UsingAlphaChannel="False" SelectedColor="Black" Margin="5,10,0,0" Height="30" ColorMode="ColorCanvas" DisplayColorAndName="True" Width="200" HorizontalAlignment="Left" FontSize="14"/>
<Label Content="Pen thickness" FontWeight="SemiBold" FontSize="16" Margin="0,25,0,0"/>
<Slider x:Name="ThicknessSlider" ValueChanged="ThicknessSlider_ValueChanged" Margin="5,10,0,0" IsSnapToTickEnabled="True" Minimum="1" Maximum="5" Value="2"/>
<Label Content="Highlighter colour" FontWeight="SemiBold" FontSize="16" Margin="0,25,0,0"/>
<StackPanel Orientation="Horizontal" Margin="5,10,0,0">
<RadioButton Name="YellowRadio" Click="YellowRadio_Click" GroupName="HighlighterRadios" Margin="0,0,15,0" IsChecked="True" VerticalContentAlignment="Center">
<Rectangle Fill="Yellow" Height="20" Width="50" Stroke="Gray"/>
</RadioButton>
<RadioButton Name="CyanRadio" Click="CyanRadio_Click" GroupName="HighlighterRadios" Margin="0,0,15,0" VerticalContentAlignment="Center">
<Rectangle Fill="Cyan" Height="20" Width="50" Stroke="Gray"/>
</RadioButton>
<RadioButton Name="MagentaRadio" Click="MagentaRadio_Click" GroupName="HighlighterRadios" VerticalContentAlignment="Center">
<Rectangle Fill="Magenta" Height="20" Width="50" Stroke="Gray"/>
</RadioButton>
</StackPanel>
<Label Content="Eraser type" FontWeight="SemiBold" FontSize="16" Margin="0,25,0,0"/>
<StackPanel Orientation="Horizontal" Margin="5,10,0,5">
<RadioButton Name="PartialStrokeRadio" Click="PartialStrokeRadio_Click" Content="Partial stroke" GroupName="EraserTypeRadios" Margin="0,0,25,0" IsChecked="True" FontSize="14" VerticalContentAlignment="Center"/>
<RadioButton Name="FullStrokeRadio" Click="FullStrokeRadio_Click" Content="Full stroke" GroupName="EraserTypeRadios" FontSize="14" VerticalContentAlignment="Center"/>
</StackPanel>
</StackPanel>
</Grid>
</Window>