2008-08-18 18 views
13

Ich arbeite an einer WinForm .Net-Anwendung mit der grundlegenden Benutzeroberfläche, die Symbolleistenschaltflächen, Menüelemente und Tastenanschläge enthält, die alle den gleichen zugrunde liegenden Code initiieren. Im Augenblick rufen die Ereignisbehandlungsroutinen für jede eine gemeinsame Methode zum Ausführen der Funktion auf.Beispiel für Befehlsmuster für UI suchen

Von dem, was ich gelesen habe, könnte diese Art von Aktion von der Command design pattern mit dem zusätzlichen Vorteil der automatischen Aktivierung/Deaktivierung oder Überprüfung/Aufhebung der UI-Elemente behandelt werden.

Ich habe das Netz nach einem guten Beispielprojekt gesucht, aber wirklich keins gefunden. Hat jemand ein gutes Beispiel, das geteilt werden kann?

Antwort

16

Lassen Sie uns zunächst sicherstellen, dass wir wissen, was das Command-Muster ist:

Befehlsmuster kapselt eine Anforderung als Objekt und gibt es eine bekannte öffentliche Schnittstelle. Das Befehlsmuster stellt sicher, dass jedes Objekt seine eigenen Befehle empfängt und eine Entkopplung zwischen Sender und Empfänger bereitstellt. Ein Sender ist ein Objekt, das eine Operation aufruft, und ein Empfänger ist ein Objekt , das die Anforderung empfängt und auf es handelt.

Hier ist ein Beispiel für Sie. Es gibt viele Möglichkeiten, wie Sie dies tun können, aber ich werde einen Interface-Basisansatz verwenden, um den Code für Sie testbarer zu machen. Ich bin mir nicht sicher, welche Sprache Sie bevorzugen, aber ich schreibe dies in C#.

Zuerst erstellen Sie eine Schnittstelle, die ein Command beschreibt.

public interface ICommand 
{ 
    void Execute(); 
} 

Zweitens, erstellen Sie Befehlsobjekte, die die Befehlsschnittstelle implementieren.

public class CutCommand : ICommand 
{ 
    public void Execute() 
    { 
     // Put code you like to execute when the CutCommand.Execute method is called. 
    } 
} 

Drittens müssen wir unsere Aufrufer oder Senderobjekt einrichten.

Viertens erstellen Sie das Clientobjekt, das das Invoker/sender -Objekt verwenden wird.

public class Client 
{ 
    static void Main() 
    { 
     TextOperations textOperations = new TextOperations(); 
     textOperation.Invoke(new CutCommand()); 
    } 
} 

Ich hoffe, dass Sie dieses Beispiel nehmen und es in Gebrauch für die Anwendung setzen Sie gerade arbeiten. Wenn Sie mehr Klarheit wünschen, lassen Sie es mich wissen.

2

Ihr auf dem richtigen Weg. Grundsätzlich haben Sie ein Modell, das das Dokument darstellt. Sie werden dieses Modell im CutCommand verwenden. Sie sollten den Konstruktor von CutCommand so ändern, dass er die Informationen akzeptiert, die Sie ausschneiden möchten. Dann sagen Sie immer, wenn Sie auf die Schaltfläche Ausschneiden klicken, rufen Sie einen neuen CutCommand auf und übergeben die Argumente im Konstruktor. Verwenden Sie dann diese Argumente in der Klasse, wenn die Execute-Methode aufgerufen wird.

1

Qt verwendet Befehlsmuster für Menüleiste/Toolbar.

QActions werden separat von QMenuItem und QToolbar erstellt, und die Aktionen können QMenuItem und QToolbar mit der Methode setAction() bzw. addAction() zugewiesen werden.

http://web.archive.org/web/20100801023349/http://cartan.cas.suffolk.edu/oopdocbook/html/menus.html

http://web.archive.org/web/20100729211835/http://cartan.cas.suffolk.edu/oopdocbook/html/actions.html

+0

Ich weiß, dass der Beitrag vor 4 Jahren war, also würde es erklären. Aber beide Verbindungen sind jetzt gebrochen. –

+1

Ersetzte defekte Links durch einen Link zu ihrer archive.org-Kopie – Imran

0

ich Sie mit Beispiel-Link nicht helfen kann, sondern beispielsweise von mir zur Verfügung stellen kann.

1) Definieren Sie ICommand-Schnittstelle:

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

2) Haben Ihre ICommand Implementierungen für konkrete Befehle, sondern auch für sie abstrakte Basisklasse definieren:

public abstract class WinFormCommand : ICommand { 

} 

3) Befehl Aufrufer erstellen:

public interface ICommandInvoker { 
    void Invoke(ICommand command); 
    void ReDo(); 
    void UnDo(); 
} 

public interface ICommandDirector { 
    void Enable(ICommand); 
    void Disable(ICommand); 
} 

public class WinFormsCommandInvoker : ICommandInvoker, ICommandDirector { 

    private readonly Dictionary<ICommand, bool> _commands; 
    private readonly Queue<ICommand> _commandsQueue;  
    private readonly IButtonDirector _buttonDirector; 

    // you can define additional queue for support of ReDo operation 

    public WinFormsCommandInvoker(ICommandsBuilder builder, IButtonDirector buttonDirector) { 
     _commands = builder.Build(); 
     _buttonDirector = buttonDirector; 
     _commandsQueue = new Queue<ICommand>(); 
    } 

    public void Invoke(ICommand command) { 
     command.Do(); 
     __commandsQueue.Enqueue(command); 
    } 

    public void ReDo() { 
     //you can implement this using additional queue 
    } 

    public void UnDo() { 
     var command = __commandsQueue.Dequeue(); 
     command.Undo(); 
    } 

    public void Enable(ICommand command) { 
     _commands.[command] = true; 
     _buttonDirector.Enable(command); 
    } 

    public void Disable(ICommand command) { 
     _commands.[command] = false; 
     _buttonDirector.Disable(command); 
    } 
} 

4) Jetzt können Sie Ihren ICommandsBuilder, IButtonDirect implementieren oder und fügen Sie WinFormsCommandInvoker andere Schnittstellen wie ICheckBoxDirector hinzu.