1

I have coded a program that will allow user to paint with pen in the Form. But there is a problem.

I can set just 2 color in the form e.g. I set Black color for left buttons and red color for right buttons.

Everything I need is how can I change this code to a code which user can choose his own Color.

I tried different ways like Color Dialogue but I couldn't.

My code:

private void Form1_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button == System.Windows.Forms.MouseButtons.Left)
    {
        Graphics graphic = this.CreateGraphics();
        graphic.DrawLine(Pens.Black, e.X, e.Y, e.X + 1, e.Y + 1);
    }

    if (e.Button == System.Windows.Forms.MouseButtons.Right)
    {
        Graphics graphic = this.CreateGraphics();
        graphic.DrawLine(Pens.Red, e.X, e.Y, e.X + 1, e.Y + 1);
    }
}
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
VorTex318
  • 23
  • 6
  • What does `CreateGraphics` do? If you're not painting to an off-screen buffer then the user's artwork will be lost when the window's client area is invalidated. – Dai Nov 17 '16 at 12:51
  • @Dai i Know I'm just trying to change this code , to a code which user can choose their own color. when i started project , this code was exactly what i wanted. Just color of the pen... – VorTex318 Nov 17 '16 at 12:54
  • 2
    Winforms graphics basic rule #1 : Never use `control.CreateGraphics`! Never try to cache a `Graphics` object! Either draw into a `Bitmap bmp` using a `Graphics g = Graphics.FromImage(bmp)` or in the `Paint` event of a control, using the `e.Graphics` parameter..The system needs to draw all the controls' surfaces at times you can't control; therefore all you want to add to those surfaces must be created from the one event that the system will call, which is the `Paint` event. – TaW Nov 17 '16 at 12:57
  • 1
    It only __seems__ to work. Askan has answered your question but it still will only seem to work. Set the two colors with a ColorDialog, try it, enjoy, minimize, maximize then __throw it all away__! – TaW Nov 17 '16 at 12:58
  • @TaW I believe I have a solution for the graphics problem in my answer – TheLethalCoder Nov 17 '16 at 13:05
  • yes, a step in the right direction. See [here](http://stackoverflow.com/questions/31988079/copying-free-hand-drawing-from-panel-in-visual-studio-2013/32112426?s=1|0.1777#32112426) and also [here](http://stackoverflow.com/questions/26936109/how-do-i-save-a-winforms-panels-drawing-content-to-a-file/26938635?s=4|0.0675#26938635) for a fuller treatment..! – TaW Nov 17 '16 at 13:09

3 Answers3

1

Use some dialog to select a colour for left and right mouse buttons and store that in a class level variable i.e.

if (_leftPen != null) { _leftPen.Dispose(); }
_leftPen = new Pen(selectedColour, 1f);

Note that 1f is the thickness of the Pen, this can be changed to meet your requirements.

Then in your drawing method just use _leftPen. Then just apply similar logic for the right mouse button i.e. _rightPen. You then have:

private Pen _leftPen = Pens.Black;
private Pen _rightPen = Pens.Red;

private void Form1_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button == System.Windows.Forms.MouseButtons.Left)
    {
        Graphics graphic = this.CreateGraphics();
        graphic.DrawLine(_leftPen, e.X, e.Y, e.X + 1, e.Y + 1);
    }

    if (e.Button == System.Windows.Forms.MouseButtons.Right)
    {
        Graphics graphic = this.CreateGraphics();
        graphic.DrawLine(_rightPen, e.X, e.Y, e.X + 1, e.Y + 1);
    }
}

All you need to do is find a way for the user to select their own colour.

Also note the comment by @Taw:

Winforms graphics basic rule #1 : Never use control.CreateGraphics! Never try to cache a Graphics object! Either draw into a Bitmap bmp using a Graphics g = Graphics.FromImage(bmp) or in the Paint event of a control, using the e.Graphics parameter..The system needs to draw all the controls' surfaces at times you can't control; therefore all you want to add to those surfaces must be created from the one event that the system will call, which is the Paint event.

You should use your code in the Paint event and in the MouseMove event you should store the positions of the line that you want to draw then update this later.

private Pen _leftPen = Pens.Black;
private Pen _rightPen = Pens.Red;

private List<Point> _leftPoints = new List<Point>();
private List<Point> _rightPoints = new List<Point>();

private void Form1_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button == System.Windows.Forms.MouseButtons.Left)
    {
        _leftPoints.Add(new Point(e.X, e.Y));
    }

    if (e.Button == System.Windows.Forms.MouseButtons.Right)
    {
        _rightPoints.Add(new Point(e.X, e.Y));
    }

    this.Invalidate();
}

private void Form1_Paint(object sender, PaintEventArgs e)
{
    foreach (Point point in _leftPoints)
    {
        e.Graphics.DrawLine(_leftPen, point.X, point.Y, point.X + 1, point.Y + 1);
    }

    //Similar code for _rightPoints here
}

Note the call to Invalidate forces the form to repaint itself. If applicable you may use this.Refresh() or this.Update() instead.

TheLethalCoder
  • 6,668
  • 6
  • 34
  • 69
1
Color BackColor = Color.Black;
Color ForeColor = Color.Red;

Then get user colors and set the Backcolor and Forecolor

      private void Form1_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.Button == System.Windows.Forms.MouseButtons.Left)
        {
            Graphics graphic = this.CreateGraphics();
            graphic.DrawLine(new Pen(ForeColor), e.X, e.Y, e.X + 1, e.Y + 1);
        }
        if (e.Button == System.Windows.Forms.MouseButtons.Right)
        {
            Graphics graphic = this.CreateGraphics();
            graphic.DrawLine(new Pen(BackColor), e.X, e.Y, e.X + 1, e.Y + 1);
        }
    }
Ashkan Mobayen Khiabani
  • 33,575
  • 33
  • 102
  • 171
0

You can use something like this:

using System;
using System.Drawing;
using System.Windows.Forms;

public partial class Form1 : Form
{
    private readonly Graphics graphics;

    public Form1()
    {
        InitializeComponent();

        this.graphics = this.CreateGraphics();

        this.Load += (s, e) =>
        {
            foreach (var color in Enum.GetValues(typeof(KnownColor)))
                this.UserColors.Items.Add(color);
        };
    }

    /// <summary>
    /// Painting (left button use changed color, right-white to erase)
    /// </summary>
    private void Form1_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
            this.graphics.DrawLine(
                new Pen(
                    Color.FromKnownColor(
                        (KnownColor)Enum.Parse(typeof(KnownColor),
                        this.UserColors.SelectedItem.ToString()))),
                e.X,
                e.Y,
                e.X + 1,
                e.Y + 1);

        if (e.Button == MouseButtons.Right)
            this.graphics.DrawLine(
                Pens.White,
                e.X,
                e.Y,
                e.X + 1,
                e.Y + 1);
    }
}

Where this.UserColors is ComboBox on your main window.

EgoPingvina
  • 734
  • 1
  • 10
  • 33