2009-01-07 4 views
18

So baue ich eine Anwendung, die viele Fenster, die alle mit dem gleichen grundlegenden Layout hat:Wie erstellt man ein Template-Fenster in WPF?

  1. ein Hauptfenster
  2. Ein Logo in der oberen Ecke
  3. Ein Titelblock
  4. A Statusanzeige unten
  5. Ein Bereich für fensterspezifische Steuerelemente.

Im Moment muss ich diese Struktur in jedem Fenster neu erstellen. Idealerweise möchte ich, dass dieses Layout an einem einzigen Ort codiert wird, vielleicht in einer benutzerdefinierten Fensterunterklasse, um die Benutzung zu vereinfachen. Hat jemand irgendwelche Anhaltspunkte dafür, wie man anfängt oder frühere Erfahrungen mit ähnlichen Problemen?

Antwort

31

Sie können ein neues ControlTemplate erstellen, das wie unten gezeigt auf ein Fenster ausgerichtet ist.

<ControlTemplate x:Key="WindowControlTemplate1" TargetType="{x:Type Window}"> 
    <Border 
     Background="{TemplateBinding Background}" 
     BorderBrush="{TemplateBinding BorderBrush}" 
     BorderThickness="{TemplateBinding BorderThickness}" 
     > 
     <Grid> 
      <Grid.RowDefinitions> 
       <RowDefinition Height="Auto"/> 
       <RowDefinition Height="0.93*"/> 
       <RowDefinition Height="Auto"/> 
      </Grid.RowDefinitions> 

      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="0.21*"/> 
       <ColumnDefinition Width="0.79*"/> 
      </Grid.ColumnDefinitions> 

      <ContentPresenter 
       Grid.ColumnSpan="2" 
       Grid.Row="1" 
       Content="{TemplateBinding Content}" 
       ContentTemplate="{TemplateBinding ContentTemplate}" 
       /> 
      <ResizeGrip 
       HorizontalAlignment="Right" 
       x:Name="WindowResizeGrip" 
       VerticalAlignment="Bottom" 
       IsTabStop="False" 
       Visibility="Collapsed" 
       Grid.Column="1" 
       Grid.Row="2" 
       /> 
      <TextBlock Text="My Logo" /> 
      <TextBlock Grid.Column="1" Text="My Title"/> 
      <StatusBar Height="20" Grid.ColumnSpan="2" Grid.Row="2"/> 
     </Grid> 
    </Border> 

    <ControlTemplate.Triggers> 
     <MultiTrigger> 
      <MultiTrigger.Conditions> 
       <Condition Property="ResizeMode" Value="CanResizeWithGrip"/> 
       <Condition Property="WindowState" Value="Normal"/> 
      </MultiTrigger.Conditions> 
      <Setter Property="Visibility" TargetName="WindowResizeGrip" Value="Visible"/> 
     </MultiTrigger> 
    </ControlTemplate.Triggers> 
</ControlTemplate> 
+0

Danke! das ist genau das, wonach ich suche! Vielen Dank :) – NoizWaves

-3

Warum genau verwenden Sie "viele Fenster?" Warum nicht nur ein einzelnes Fenster mit einem Tab-Steuerelement? Oder ein einzelnes Fenster mit Benutzerkontrollen?

Unabhängig davon, um Ihre Frage zu beantworten, Benutzercontrols sind eine Möglichkeit, wie Sie die Funktionalität, die Sie beschreiben wollen, erhalten wollen.

Erstellen Sie eine neue Window-Klasse, und haben Sie eine "Childrens" -Eigenschaft, mit der ein Objekt in das Dock-Panel eingebettet werden kann, wo die "fensterspezifischen Steuerelemente" angezeigt werden sollen.

Wenn Sie neue Fenster starten, instanziieren Sie den Fenstertyp und ein Benutzersteuerelement mit den entsprechenden Steuerelementen, fügen Sie das Benutzersteuerelement der Children-Eigenschaft Ihres Fensters hinzu, und zeigen Sie das Fenster an. Sie können sogar Event-Handler, DataContexts und was nicht zu diesem Zeitpunkt binden.

+1

Warum so viele downvotes? Scheint wie eine gültige Frage zu mir, vielleicht nicht die ideale Antwort, aber es ist definitiv eine Überlegung wert für die richtige Situation. – MikeKulls

+0

Denn während es eine Lösung darstellt, beantwortet es die Frage nicht wirklich. Darüber hinaus ist es eine sehr brutale Methode der Lösung. Eigentlich würde ich es als eine WINFORMS-Methode beschreiben, um es über eine WPF zu lösen (was die ausgewählte Antwort ist). –

+0

Vielleicht konzentrieren Sie sich zu sehr auf das Bit "Single Window mit einem Tab-Steuerelement" ?? Das einzige Fenster mit austauschbaren Bedienelementen ist eine perfekte Lösung in der richtigen Situation. Es ist die einzige Lösung, die Code-Duplizierung vermeidet, wenn Sie mehr als 1 Fenster haben, dann muss Code jeder Art, egal wie klein, in jedem dieser Fenster dupliziert werden. Wenn Änderungen erforderlich sind, muss dieser Code an mehreren Standorten geändert werden. Es ist kein Deal Break, aber es ist eine Überlegung wert. – MikeKulls

6

Wenn Sie mutig genug sind, eine große architektonische Verschiebung zu machen, könnten Sie CompositeWPF (früher Codename Prism) von den Patterns & Practices guys bei Microsoft betrachten.

Von Interesse für Sie wäre die Möglichkeit, "Regionen" in einer Shell (d. H. Fenster) zu definieren und dann Ansichten zu verwenden, um die Regionen zu füllen. Es verwendet das Model-View-Presenter-Muster, um eine unabhängige Entwicklung von "Ansichten" aus dem Modell zu ermöglichen, die im Laufe der Zeit einfach verschoben werden können, da die Shell nur Regionen definiert und nicht direkt mit dem verbunden ist. Im Prinzip hilft das, die Shell von den Ansichten und den Ansichten voneinander zu entkoppeln und es einfacher zu machen, Unit-Test zu machen ... blah, blah blah.

Es ist ein großer Sprung und etwas, das Sie am Anfang verlangsamen wird, obwohl Ihre Situation eine der Arten von Anwendungen ist, die CompositeWPF adressieren soll.

Als Teil von CompositeWPF müssen Sie verschiedene Muster berücksichtigen, die Neulinge z. UnityContainer, Inversion-of-Control, MVP (oder Model/view/view-model) und Dependency Injection.

kann ich erinnere mich, als ich mit den Beispielanwendungen sind verwirrt zuerst gestartet, weil es die einige der Ansichten nicht klar, wie auf der Erde ist selbst erstellt werden wurden! Der Einheitsbehälter wird Objekte instanziieren und parametrisierte Konstruktoren magisch aufrufen.

CompositeWPF ist eine elegante Lösung für Ihre Frage, aber keine einfache oder unkomplizierte. Nachdem ich CompositeWPF in meinem letzten Projekt verwendet habe, beabsichtige ich, es für die nächste geeignete Anwendung wieder zu verwenden.

+0

Vielen Dank für Ihre detaillierte Einführung in CompositeWPF. Ich habe die Composite Application Guidance für WPF heruntergeladen und bin noch verwirrter geworden. Ich habe mich gefragt, ob es ein einfaches Beispiel für einen neuen User gibt. – Picflight

+0

@Picflight: Hier ist ein Link zu einem Artikel von Brian Noyes über DevX http://www.devx.com/codemag/Article/40165/1763. Wo immer Sie Beispielcode erhalten können, verwenden Sie den Debugger, um zu lernen, wie die Dinge funktionieren. Setzen Sie Haltepunkte auf die Konstruktoren von Klassen und gehen Sie den Aufruf-Stack hinauf, um zu sehen, wie es funktioniert. – Rhys

2

Der einfachste Ansatz ist, WPF eine "Seite" für die fensterspezifischen Steuerelemente zu erstellen und ein "Frame" im Hauptfenster zu platzieren. Sie können sogar eine nette Navigation auf diese Weise erstellen.