بهار آموزش با تخفیف های شگفت انگیز توسینسو بهار آموزش با تخفیف های شگفت انگیز توسینسو
مانده تا پایان تخفیف
مشاهده دوره ها
0

پیاده سازی undo & redo در برنامه paint با سی شارپ

درووود به همه دوستان و اساتید عزیز .

یه برنامه paint به وسیله سی شارپ ساختم که میخام امکان undo & redo هم داشته باشه . واسه این کار از پشته استفاده کردم ولی خب متاسفانه جواب نمیده و نمیدونمم که مشکل از کجاست . اگه کسی در این رابطه اطلاعاتی داره لطفا راهنمایی کنه . خیلی ضروریه . ضمنا کد های برناممو این پایین گذاشتم که میتونید ببینید . با سپاس فراوان

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;

namespace Saman_drawing_board
{
    public partial class Form1 : Form
    {
        public void undo()
        {
            lock (_undoRrdolocker)
            {
                if (_undostack.Count > 0)
                {
                    _redostack.Push(_undostack.Pop());
                    pictureBox1.Image = _redostack.Peek();
                    pictureBox1.Refresh();
                }

            }

        }
        public void redo()
        {
            lock (_undoRrdolocker)
            {
                if (_redostack.Count > 0)
                {
                    _undostack.Push(_redostack.Pop());
                    pictureBox1.Image = _undostack.Peek();
                    pictureBox1.Refresh();

                }
            }
        }

        public Form1()
        {
            InitializeComponent();
        }
        Bitmap bmp;
        int x, y;
        Color currentcolor = Color .Black;
        string act = "";
        int drawingsize = 2;
        int x1, y1;
        int x2, y2;
        Rectangle rect = new Rectangle(0, 0, 0, 0);


        private Stack<Image> _undostack = new Stack<Image>();
        private Stack<Image> _redostack = new Stack<Image>();
        private readonly object _undoRrdolocker = new object();

       


        private void groupBox1_Enter(object sender, EventArgs e)
        {

        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height);
        }
        private void settool(PictureBox pic)
        {
            pictureBox2.BorderStyle = pictureBox3.BorderStyle = pictureBox5.BorderStyle = BorderStyle.None;
            pic.BorderStyle = BorderStyle.FixedSingle;
        }
        private void setcolor(PictureBox pic)
        {
            currentcolor = pic.BackColor;
            pictureBox13.BackColor = currentcolor;
        }



        private void pictureBox2_Click(object sender, EventArgs e)
        {
            label1.Visible = false;
            settool(pictureBox2);
            act = "pen";
            pictureBox1.Cursor = Cursors.Cross;
            pictureBox14.Visible = false;
            pictureBox16.Visible = false;
            pictureBox18.Visible = false;
            pictureBox19.Visible = false;
            pictureBox20.Visible = false;

        }

        private void pictureBox3_Click(object sender, EventArgs e)
        {
            label1.Visible = false;
            settool(pictureBox3);
            pictureBox1.Cursor = Cursors.Cross;
            act = "eraser";
            pictureBox14.Visible = false;           
            pictureBox16.Visible = false;
            pictureBox18.Visible = false;
            pictureBox19.Visible = false;
            pictureBox20.Visible = false;
        }

        private void pictureBox5_Click(object sender, EventArgs e)
        {
            label1.Visible = false;
            settool(pictureBox5);
            pictureBox14.Visible = true;
            pictureBox16.Visible = true;
            pictureBox18.Visible = true;
            pictureBox19.Visible = true;
            pictureBox20.Visible = true;
            act = "shape";
        }

      

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {

               Graphics g = Graphics.FromImage(bmp);
               Pen p = new Pen(currentcolor, drawingsize);
               SolidBrush brush = new SolidBrush(Color.White);
               if (act == "pen")
               {
                   if (e.Button == MouseButtons.Left)
                   {
                       g.DrawLine(p, x, y, e.X, e.Y);
                       x = e.X;
                       y = e.Y;

                   }
                   x = e.X;
                   y = e.Y;
                   pictureBox1.Image = bmp;
                   _undostack.Push(pictureBox1.Image);
               }
               else if (act == "eraser")
               {
                   if (e.Button == MouseButtons.Left)
                   {
                       g.FillEllipse(brush, new Rectangle(e.X - drawingsize, e.Y - drawingsize, drawingsize * 5, drawingsize * 5));
                       pictureBox1.Image = bmp;
                       _undostack.Push(pictureBox1.Image);
                   }

               }

               else if (act == "shape-line")
               {
                   if (e.Button == MouseButtons.Left)
                   {
                       pictureBox1.Image = bmp;
                       Bitmap temp = new Bitmap(bmp);
                       Graphics g1 = Graphics.FromImage(temp);
                       g1.DrawLine(p, x1, y1, e.X, e.Y);
                       pictureBox1.Image = temp;
                       _undostack.Push(pictureBox1.Image);

                   }
               }
               else if (act == "shape-rect")
               {
                   if (e.Button == MouseButtons.Left)
                   {
                       pictureBox1.Image = bmp;
                       Bitmap temp = new Bitmap(bmp);
                       Graphics g1 = Graphics.FromImage(temp);
                       if (e.X - x1 > 0 && e.Y - y1 > 0)
                       {
                           rect = new Rectangle(x1, y1, e.X - x1, e.Y - y1);
                       }
                       if (e.X - x1 < 0 && e.Y - y1 > 0)
                       {
                           rect = new Rectangle(e.X, y1, x1 - e.X, e.Y - y1);
                       }
                       if (e.X - x1 > 0 && e.Y - y1 < 0)
                       {
                           rect = new Rectangle(x1, e.Y, e.X - x1, y1 - e.Y);
                       }
                       if (e.X - x1 < 0 && e.Y - y1 < 0)
                       {
                           rect = new Rectangle(e.X, e.Y, x1 - e.X, y1 - e.Y);
                       }
                       g1.DrawRectangle(p, rect);
                       pictureBox1.Image = temp;
                       _undostack.Push(pictureBox1.Image);

                   }
               }
               else if (act == "shape-circle")
               {
                   if (e.Button == MouseButtons.Left)
                   {
                       pictureBox1.Image = bmp;
                       Bitmap temp = new Bitmap(bmp);
                       Graphics g1 = Graphics.FromImage(temp);
                       if (e.X - x1 > 0 && e.Y - y1 > 0)
                       {
                           rect = new Rectangle(x1, y1, e.X - x1, e.Y - y1);
                       }
                       if (e.X - x1 < 0 && e.Y - y1 > 0)
                       {
                           rect = new Rectangle(e.X, y1, x1 - e.X, e.Y - y1);
                       }
                       if (e.X - x1 > 0 && e.Y - y1 < 0)
                       {
                           rect = new Rectangle(x1, e.Y, e.X - x1, y1 - e.Y);
                       }
                       if (e.X - x1 < 0 && e.Y - y1 < 0)
                       {
                           rect = new Rectangle(e.X, e.Y, x1 - e.X, y1 - e.Y);
                       }
                       g1.DrawEllipse(p, rect);
                       pictureBox1.Image = temp;
                       _undostack.Push(pictureBox1.Image);

                   }
               }

               else if (act == "shape-mosalas")
               {
                   if (e.Button == MouseButtons.Left)
                   {
                       pictureBox1.Image = bmp;
                       Bitmap temp = new Bitmap(bmp);
                       Graphics g1 = Graphics.FromImage(temp);

                       Point[] points = { new Point(x1, y1), new Point(e.X - x1, e.Y - y1), new Point((x1 + (e.X - x1)) / 2, e.Y) };
                       g1.DrawPolygon(p, points);
                       pictureBox1.Image = temp;
                       _undostack.Push(pictureBox1.Image);

                   }
               }
  
        }

        private void pictureBox4_Click(object sender, EventArgs e)
        {
            setcolor(pictureBox4);
        }

        private void pictureBox6_Click(object sender, EventArgs e)
        {
            setcolor(pictureBox6);
        }

        private void pictureBox8_Click(object sender, EventArgs e)
        {
            setcolor(pictureBox8);
        }

        private void pictureBox7_Click(object sender, EventArgs e)
        {
            setcolor(pictureBox7);
        }

        private void pictureBox12_Click(object sender, EventArgs e)
        {
            setcolor(pictureBox12);
        }

        private void pictureBox11_Click(object sender, EventArgs e)
        {
            setcolor(pictureBox11);
        }

        private void pictureBox10_Click(object sender, EventArgs e)
        {
            setcolor(pictureBox10);
        }

        private void pictureBox9_Click(object sender, EventArgs e)
        {
            setcolor(pictureBox9);
        }

        private void radioButton1_CheckedChanged(object sender, EventArgs e)
        {
            if (radioButton1.Checked) {
                drawingsize = 2;
            }
        }

        private void radioButton2_CheckedChanged(object sender, EventArgs e)
        {
            if (radioButton2.Checked)
            {
                drawingsize = 3;
            }
        }

        private void radioButton3_CheckedChanged(object sender, EventArgs e)
        {
            if (radioButton3.Checked)
            {
                drawingsize = 4;
            }
        }

        private void radioButton4_CheckedChanged(object sender, EventArgs e)
        {
            if (radioButton4.Checked)
            {
                drawingsize = 5;
            }
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                OpenFileDialog op = new OpenFileDialog();
                if (op.ShowDialog() == DialogResult.OK) {
                    pictureBox1.Image = Image.FromFile(op.FileName);
                    bmp = (Bitmap)pictureBox1.Image;
                }
            }
            catch (Exception ex) {
                MessageBox.Show(ex.Message);
            }
        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveFileDialog save = new SaveFileDialog();
            save.Filter = " image files |*.jpg|*.gif|*.bmp|";
            save.ShowDialog();
            pictureBox1.Image.Save(save.FileName);
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

   
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (MessageBox.Show("آیا برای خروج مطمئن هستید؟", "exit", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                Application.Exit();
            }
            else
                e.Cancel = true;
        }

        private void pictureBox14_Click(object sender, EventArgs e)
        {
            act = "shape-line";
            label1.Visible = false;

        }

        private void pictureBox15_Click(object sender, EventArgs e)
        {
            act = "shape-sequar";
            label1.Visible = false;
        }

        private void pictureBox16_Click(object sender, EventArgs e)
        {
            act = "shape-rect";
            label1.Visible = false;
        }

        private void pictureBox18_Click(object sender, EventArgs e)
        {
            act = "shape-circle";
            label1.Visible = false;
        }

        private void pictureBox17_Click(object sender, EventArgs e)
        {
            act = "shape-bey";
            label1.Visible = false;
        }

        private void pictureBox20_Click(object sender, EventArgs e)
        {
            act = "shape-mosalas";
            label1.Visible = false;
        }

        private void pictureBox19_Click(object sender, EventArgs e)
        {
            act = "shape-poly";
            label1.Visible = true;
        }

        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            x1 = e.X;
            y1 = e.Y;
            undoToolStripMenuItem.Enabled = true;

        }

        private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {
            Graphics g = Graphics.FromImage(bmp);
            Pen p = new Pen(currentcolor, drawingsize);
            if (act == "shape-line")
            {
                if (e.Button == MouseButtons.Left)
                {
                    g.DrawLine(p, x1, y1, e.X, e.Y);
                    pictureBox1.Image = bmp;
                    _undostack.Push(pictureBox1.Image);
                }
            }

            else if (act == "shape-rect")
            {
                if (e.Button == MouseButtons.Left)
                {
                    g.DrawRectangle(p, rect);
                    pictureBox1.Image = bmp;
                    _undostack.Push(pictureBox1.Image);

                }
            }
            else if (act == "shape-circle")
            {
                if (e.Button == MouseButtons.Left)
                {
                    g.DrawEllipse(p, rect);
                    pictureBox1.Image = bmp;
                    _undostack.Push(pictureBox1.Image);

                }
            }
            else if (act == "shape-poly")
            {
                if (e.Button == MouseButtons.Left)
                {
                    g.DrawLine(p, x2, y2, e.X, e.Y);
                    x2 = e.X;
                    y2 = e.Y;
                }
                if (e.Button == MouseButtons.Right)
                {
                    x2 = e.X;
                    y2 = e.Y;
                }
                pictureBox1.Image = bmp;
                _undostack.Push(pictureBox1.Image);
            }

            else if (act == "shape-mosalas")
            {
                if (e.Button == MouseButtons.Left)
                {
                    Point[] points = { new Point(x1, y1), new Point(e.X - x1, e.Y - y1), new Point((x1 + (e.X - x1)) / 2, e.Y) };
                    g.DrawPolygon(p, points);
                    pictureBox1.Image = bmp;
                    _undostack.Push(pictureBox1.Image);

                }
            }
        }

        private void undoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            undo();
            redoToolStripMenuItem.Enabled = true;
            undoToolStripMenuItem.Enabled = false;         
        }


        private void redoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            redo();
            redoToolStripMenuItem.Enabled = false;
            undoToolStripMenuItem.Enabled = true;
            
        }

    }
}

پرسیده شده در 1394/09/20 توسط

2 پاسخ

0

سلام

ببخشید من اون قسمت undoRrdolocker رو قبلا از برنامم حذف کردم اینجا یادم رفته ویرایشش کنم . با این undoRrdolocker کاری نداریم . الان من باید چیکار کنم که این undo redo کار کنه .

اینم اون قسمته که حذفش کردم

private void UpdateImageData(Action updateImage)
{
    lock (_undoRedoLocker)
    {
        _undoStack.Push(pictureBox1.Image);//image);

        try
        { 
            //manipulate the image here.
            updateImage();
        }
        catch
        {
            _undoStack.Pop();//because of exception remove the last added frame from stack
            throw;
        }
    }
}
پاسخ در 1394/09/20 توسط
0

متغیر فقط خواندنی undoRrdolocker کارش چیه؟

چرا تابع های undo و redo که از متغیر undoRrdolocker استفاده می کنن قبل از تعریف متغیر undoRrdolocker نعریف کردی؟

پاسخ در 1394/09/20 توسط

پاسخ شما