Frage

Ich bin eine WinForms-Anwendung in C # entwickeln. Ich habe begrenzte Erfahrung in der GUI-Programmierung, und ich habe sehr viel auf der Fliege zu lernen. That being said, hier ist was ich bin Gebäude.

Sehen Sie die allgemeinen GUI Blick auf den folgenden Link:

GUI http://img227.imageshack.us/img227/1084/program0.jpg

Nun, ich habe viel von der Arbeit bereits getan, aber in dem sehr schlechten Autonomous Design-Muster. Ich wusste nicht, das Projekt würde jemals eine bestimmte Größe erreichen, und als solches ist es Zeit, einige große Refactoring zu tun.

Ich habe viel über die GUI-Design-Muster studiert, und das Muster, das ich umsetzen bin zu wollen ist die Passive-Ansicht (siehe http://martinfowler.com/eaaDev/PassiveScreen.html ). Ich bin auf der Suche nach etwas Hilfe auf, wie das alles zusammen zu bringen.

Hintergrund:

1) Je nachdem, was der Benutzer klickt in dem „TreeView“, die „Liste“ in der unteren linken Ecke wird eine Liste der Objekte angezeigt werden, die den „Editor“ Bereich bevölkern kann. Diese Objekte können eine TextBox oder ein Datagridview sein. Der Benutzer schaltet die Liste zu wählen, was er / sie im „Editor“

sehen will

2) Das Modell ist im Wesentlichen ein Ordner mit Daten und Konfigurationsdateien. Es ist ein externes Programm, das läuft auf einem bestimmten Verzeichnis erstellt Ausgabedateien / Ordner usw. Dieses Programm, das ich entwickeln werde wurde entwickelt, um effektiv zu verwalten / configure diese Objekte in einer benutzerfreundlichen Art und Weise

3) Das Problem mit der Art und Weise habe ich Dinge getan ist, dass es fast unmöglich zu Test nächsten ist, und daher der Umzug in die MVP-esque Passive Ansicht Entwurfsmuster

Ich versuche, es so zu machen, dass das Programm arbeitet unabhängig von der Ansicht. Ich habe nicht in der Lage gewesen, keine Beispiele zu finden, wo eine komplexere, interaktive Darstellung mit den Passiv Ansicht Mustern verwendet wird.

Fragen:

1) Bedarf Muß du eine große Schnittstelle / Ansicht für den gesamten „Look“ des Programms zu implementieren, dann implementieren Unterschnittstellen / Unteransichten für jeden des TreeView, Editor, Logger usw.? Oder gibt es eine bessere „Struktur“, dies zu tun?

2) Wenn es um die „Übergabe off“ Ereignisse aus der Sicht auf den Moderator / Controller (was auch immer Sie wünschen Terminologie w.r.t. die Passiv Ansicht Entwurfsmuster) verwenden, was ist die Art, wie ich sein soll, dies zu tun? Manchmal habe ich einfache Eigenschaften, dass Bedarf aktualisiert werden, und manchmal brauche ich eine ganze Reihe von Schritten zu entfalten.

Ich möchte Anregungen und Ratschläge zu diesem Thema Liebe. Ich habe das Internet durchforstet, und ich habe festgestellt, nicht ausreichend Beispiele, mir zu helfen, mit diesem Projekt weiter.

Vielen Dank im Voraus!

Daniel

War es hilfreich?

Lösung

Hier ist ein einfaches Beispiel, das das Konzept der passiven Ansichten mit dem MVP-Entwurfsmuster zeigt. Weil wir passive Ansichten verwenden die Ansicht hat keine Kenntnis von den Vortragenden. Der Moderator wird einfach auf Ereignisse abonnieren, indem Sie die Ansicht veröffentlicht und entsprechend handeln.

Zum starten wir brauchen einen Vertrag für unsere Ansicht zu definieren. Dies wird in der Regel eine Schnittstelle erreicht unter Verwendung von im Wesentlichen wissen, wollen wir eine sehr lose Kopplung mit unserer Sicht haben. Wir wollen die Möglichkeit, Schalter auf verschiedene Ansichten oder ein Ereignis erstellen mock Ansichten für Unit-Tests.

Hier ist ein Vertrag, der eine einfache Ansicht beschreibt, die Anzeige Kundeninformationen verwendet wird,

public interface ICustomerManagementView
{
    void InitializeCustomers(ICustomer[] customers);
    void DisplayCustomer(ICustomer customer);
    event EventHandler<EventArgs<ICustomer>> SelectedCustomerChanged;
}

Es stellt eine einzelne Methode InitializeCustomers , die verwendet werden unsere Ansicht nach mit Objekten aus unserem Modell zu initialisieren.

Wir haben auch ein Ereignis SelectedCustomerChanged , die von unserem Moderator verwendet wird eine Benachrichtigung zu erhalten, dass eine Aktion in der Ansicht aufgetreten ist.

Sobald wir unseren Vertrag haben, können wir beginnen, diese Interaktionen in unseren Vortragenden zu behandeln.

public class CustomerManagementPresenter
{
    private ICustomer _selectedCustomer;
    private readonly ICustomerManagementView _managementView;
    private readonly ICustomerRepository _customerRepository;

    public CustomerManagementPresenter(ICustomerManagementView managementView, ICustomerRepository customerRepository)
    {
        _managementView = managementView;
        _managementView.SelectedCustomerChanged += this.SelectedCustomerChanged;

        _customerRepository = customerRepository;

        _managementView.InitializeCustomers(_customerRepository.FetchCustomers());
    }

    private void SelectedCustomerChanged(object sender, EventArgs<ICustomer> args)
    {
        // Perform some logic here to update the view
        if(_selectedCustomer != args.Value)
        {
            _selectedCustomer = args.Value;
            _managementView.DisplayCustomer(_selectedCustomer);
        }
    }
}

In dem Präsentator wir ein weiteres Design-Muster Dependency Injection genannt verwenden können, den Zugang zu unserer Sicht bieten und alle Modellklassen, dass wir benötigen. In diesem Beispiel habe ich eine CustomerRepository, das zum Abrufen von Kundendaten verantwortlich ist.

Im Konstruktor wir zwei wichtigen Zeilen Code haben, erstens wir zum SelectedCustomerChanged Ereignisse in unserer Ansicht abonniert haben, es ist hier, dass wir im Zusammenhang Aktionen ausführen können. Zweitens haben wir InitilaizeCustomers mit Daten aus dem Repository bezeichnet.

An diesem Punkt haben wir nicht wirklich eine konkrete Umsetzung für unsere Ansicht definiert, alles, was wir tun müssen, um ein Objekt zu erstellen, dass Arbeitsgeräte ICustomerManagementView . Zum Beispiel in einer Anwendung von Windows Forms wir folgende

tun können
public partial class CustomerManagementView : Form, ICustomerManagementView
{
    public CustomerManagementView()
    {
        this.InitializeComponents();
    }

    public void InitializeCustomers(ICustomer[] customers)
    {
        // Populate the tree view with customer details
    }

    public void DisplayCustomer(ICustomer customer)
    {
        // Display the customer...
    }

    // Event handler that responds to node selection
    private void CustomerTreeViewAfterSelect(object sender, TreeViewEventArgs e)
    {
        var customer = e.Node.Tag as ICustomer;
        if(customer != null)
        {
            this.OnSelectedCustomerChanged(new EventArgs<ICustomer>(customer));
        }
    }

    // Protected method so that we can raise our event
    protected virtual void OnSelectedCustomerChanged(EventArgs<ICustomer> args)
    {
        var eventHandler = this.SelectedCustomerChanged;
        if(eventHandler != null)
        {
            eventHandler.Invoke(this, args);
        }
    }

    // Our view will raise an event each time the selected customer changes
    public event EventHandler<EventArgs<ICustomer>> SelectedCustomerChanged;
}

Wenn wir unsere Präsentationslogik testen wollten könnten wir unsere Ansicht verspotten und einige Behauptungen durchführen.

EDIT: Inklusive benutzerdefiniertes Ereignis args

public class EventArgs<T> : EventArgs
{
    private readonly T _value;

    public EventArgs(T value)
    {
        _value = value;
    }

    public T Value
    {
        get { return _value; }
    }
}

Andere Tipps

Ich würde sie brechen in verschiedenen Ansichten mit ihren eigenen Geschenke, und verwenden Sie eine „Steuerung“ Moderator / view Nachricht Delegation zwischen ihnen allen zu verwalten. Nicht nur wird diese Hilfe Testbarkeit aber es wird halten Sie Ihre Kontrollen SRP erfüllen, auch.

So in Ihrem Fall möglicherweise eine IFormManager haben, die Ihr Hauptfenster implementieren und dann ein IFileManager, ILoggerWindow usw. etc.

Obwohl es ein bisschen übertrieben zu Nutzen sein könnte, würde ich vorschlagen, dass Sie einen Blick auf Smart Client Software Factory haben (von dem Microsoft Patterns and Practices-Team) - es ist nicht aktiv nicht mehr entwickelt, aber es hat eine gute Umsetzung von MVP und macht diese Art von Sachen Komposition Blick recht gut, könnte man einige gute Ideen so geben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top