Skip to main content

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
    }
}

Enjoying this tutorial?


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>