命令模式将所有命令推送到堆栈

时间:2015-05-24 06:50:06

标签: c# winforms design-patterns controls

我有两个自定义Control类,BoxEllipse。我能够绘制,拖动和调整它们的大小。现在我尝试实现无限制的撤销和重做。我为此使用了Command Pattern。我的Box类看起来与Ellipse类完全相同,区别在于Box类描绘了一个盒子形状。在我绘制Ellipse并且例如移动/调整此控件的时刻,我能够退后一步,因为添加使堆栈大小为1,而一次撤消使堆栈大小再次为0。只有当我添加Ellipse时,我才会立即将命令推送到Stack。调整大小/移动发生在另一个类然后添加,但这些操作也必须推送到commandStack中的Form1。我怎么能这样做?

我的想法是在EllipseBox中创建一个堆栈,并为每个操作调用Do并将每个命令推送到堆栈(在Ellipse或{{1 }}),但这不会起作用我相信因为Box类需要使用来自所有Form的所有命令来访问堆栈。有谁可以帮助进行无限制的撤销/重做工作? 我按照此链接中的示例进行了操作:http://www.c-sharpcorner.com/uploadfile/40e97e/command-pattern-undo-example/

ICommand界面

Controls

椭圆类

public interface ICommand
{
    void Do();
    void Undo();
}

表单类

class Ellipse : Control, ICommand
{
    private Point mDown { get; set; }

    public Ellipse()
    {
        SetStyle(ControlStyles.SupportsTransparentBackColor, true);
        this.BackColor = Color.Transparent;
        this.DoubleBuffered = true;
        this.ResizeRedraw = true;
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        // Draw a black ellipse in the rectangle represented by the control.
        e.Graphics.FillEllipse(Brushes.Black, 0, 0, Width, Height);

    }  

    protected override void OnMouseDown(MouseEventArgs e)
    {
        base.OnMouseDown(e);
        mDown = e.Location;
    }

    protected override void OnMouseMove(MouseEventArgs e)
    {
        // Call MyBase.OnMouseMove to activate the delegate. 
        base.OnMouseMove(e);


        if (e.Button == MouseButtons.Left)
        {
            Location = new Point(e.X + Left - mDown.X, e.Y + Top - mDown.Y);
        }

    }

    /* Allow resizing at the bottom right corner */
    protected override void WndProc(ref Message m)
    {
        const int wmNcHitTest = 0x84;
        const int htBottomLeft = 16;
        const int htBottomRight = 17;
        if (m.Msg == wmNcHitTest)
        {
            int x = (int)(m.LParam.ToInt64() & 0xFFFF);
            int y = (int)((m.LParam.ToInt64() & 0xFFFF0000) >> 16);
            Point pt = PointToClient(new Point(x, y));
            Size clientSize = ClientSize;
            if (pt.X >= clientSize.Width - 16 && pt.Y >= clientSize.Height - 16 && clientSize.Height >= 16)
            {
                m.Result = (IntPtr)(IsMirrored ? htBottomLeft : htBottomRight);
                return;
            }
        }
        base.WndProc(ref m);
    }

    int x;
    int y;
    int height;
    int width;


    private void SaveCurrentControl()
    {
        x = this.Left;
        y = this.Top;
        height = this.Height;
        width = this.Width;
    }

    public void Do()
    {
        SaveCurrentControl();
    }

    public void Undo()
    {
        this.Left = x;
        this.Top = y;
        this.Height = height;
        this.Width = width;
    }
}

0 个答案:

没有答案