Làm thế nào để tôi liên kết các đối tượng lệnh với người nhận bên phải?


9

Tôi đã cố gắng sử dụng Mẫu lệnh để triển khai Hoàn tác và Làm lại trong dự án của mình

public abstract class Command
{
    protected Form Receiver { set; get; }
    protected HtmlElement Element { set; get; }
    abstract public void ReDo();
    abstract public void UnDo();
    public Command(Form receiver)
    {
        this.Receiver = receiver;
    }
}
class AddElementCmd : Command
{        
    public AddElementCmd(HtmlElement elem, Form receiver)
        : base(receiver)
    {
        Element = elem;
    }
    public override void ReDo()
    {
        ((FormEdit)Receiver).AddElement(Element,false);
    }
    public override void UnDo()
    {
        ((FormEdit)Receiver).DelElement(Element, false);
    }
}
class DelElementCmd : Command
{
    public DelElementCmd(HtmlElement elem, Form receiver)
        : base(receiver)
    {
        Element = elem;
    }
    public override void ReDo()
    {
        ((FormEdit)Receiver).DelElement(Element, false);
    }
    public override void UnDo()
    {
        ((FormEdit)Receiver).AddElement(Element, false);
    }
}

Thực hiện AddElementlệnh trong FormEdit.

public void AddElement(HtmlElement elem, bool isNew = true)
{
    IHTMLElement2 dom = elem.DomElement as IHTMLElement2;
    if (isNew)
    {
        Command cmd = new AddElementCmd(elem, this);
        Undo.Push(cmd);
        Redo.Clear();
    }    
    // some codes here....
    if (showAlltoolStripButton.Checked)
    {
        dom.runtimeStyle.visibility = "hidden";
    }
    else if (showSelectionToolStripButton.Checked)
    {
        dom.runtimeStyle.visibility = "visible";
    }
 }
...

các ngăn xếp UndoRedođược lưu trữ trong FormMainlớp và được chuyển đến dạng trình soạn thảo.

public Stack<Command> Undo = new Stack<Command>();
public Stack<Command> Redo = new Stack<Command>();

....
FormEdit editor = new FormEdit ();
editor.Browser = webBrowser1;
editor.addedElements = addedElements;
editor.restoreElements = restoreElements;
editor.Undo = Undo;
editor.Redo = Redo;

Khi ở trạng thái mới FormEdit, người dùng nhấp vào nút Làm lại hoặc Hoàn tác, chức năng tương ứng trong đó FormEditđược thực thi, nhưng khi tôi kiểm tra bộ nhận lệnh này là hình thức mà lệnh được tạo lần đầu tiên và bây giờ có thể đã bị loại bỏ. Tôi hy vọng rằng chương trình đưa ra một lỗi, nhưng có vẻ như Commandđối tượng lưu trữ một tham chiếu đến biểu mẫu cũ và điều này dẫn đến hành vi sai.

Do đó, tôi nghĩ rằng tôi phải tìm một bộ thu phù hợp cho các lệnh, dưới dạng chính hoặc điều khiển webBrowser, có cùng thời gian với chính các lệnh. Nhưng tôi nên có quyền truy cập vào một số điều khiển liên quan đến các lệnh.

Đâu là nơi tốt nhất để thực hiện các chức năng lệnh như là người nhận các Commandđối tượng? Hoặc bất kỳ cách nào khác để liên kết biểu mẫu mới với một lệnh xuất hiện từ ngăn xếp.


Tôi nghĩ rằng quyết định này là ở bạn. Chúng tôi không thể giúp bạn vì chúng tôi không biết các đặc điểm kỹ thuật hoặc yêu cầu chức năng của ứng dụng của bạn.
Euphoric

8
Tôi tin rằng các đối tượng Command chỉ nên chứa dữ liệu tuần tự hóa (nghĩa là không có tham chiếu đến các đối tượng khác) vì các cách sử dụng phổ biến cho chúng bao gồm gửi các biểu mẫu được tuần tự hóa của chúng qua các mạng, lưu chúng vào một tệp để sau hoặc phát lại chúng trên một máy thu khác (nếu bạn muốn thay đổi của bạn để hiển thị trên màn hình của tôi trong thời gian thực, ví dụ). Điều đó có thể có nghĩa là bạn muốn truyền vào Người nhận cho từng phương thức lệnh hoặc có thể cung cấp cho các phương thức của exec execCommand () / undoCommand () để nó tự truyền vào hoặc có thể sử dụng các đối tượng lệnh chỉ chứa tên / đối số phương thức thay vì mã .
Ixrec


@Ixrec Cảm ơn bạn đã cho lời khuyên của bạn, sau đó bạn có nghĩa là tôi sẽ có thể thiết lập Receivertừng đối tượng lệnh, tôi sẽ làm điều này.
Ahmad

Thay vào đó hãy xem xét sử dụng mẫu memento.
P. Roe

Câu trả lời:


1

Mẫu lệnh nên áp dụng cho mô hình chứ không phải UI. Trong trường hợp của bạn, làm cho nó

protected HtmlDocument Receiver { set; get; }
protected HtmlElement Element { set; get; }

Để cập nhật giao diện người dùng, hãy sử dụng mẫu Observer , vì vậy tất cả các biểu mẫu mở và các điều khiển của chúng có thể phản ứng với các thay đổi trong mô hình bên dưới.

Mã của bạn sẽ trở nên rõ ràng hơn và tách rời hơn vì Command chỉ có thể thay đổi tài liệu và người quan sát trong UI chỉ phải cập nhật các điều khiển mà không quan tâm đến chính xác những gì đã thay đổi.

Khi một biểu mẫu đóng lại, nó sẽ tự hủy đăng ký như một người quan sát và không có tài liệu tham khảo nào về nó sẽ được lưu giữ.

Nếu một hình thức mới được mở sau khi thay đổi tài liệu, nó sẽ được thông báo sau khi hoàn tác ngay cả khi nó không xuất hiện khi thay đổi ban đầu được thực hiện.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.