custom control c# wpf wpf-controls

c# - control - windows presentation foundation



¿Cómo hacer una ventana de plantilla en WPF? (4)

Así que estoy construyendo una aplicación que tendrá muchas ventanas, todas con el mismo diseño básico:

  1. Una ventana principal
  2. Un logo en la esquina superior
  3. Un bloque de título
  4. Un visualizador de estado en la parte inferior
  5. Un área para controles específicos de ventana.

Por el momento, tengo que recrear esta estructura en cada ventana. Idealmente, quiero que este diseño se codifique en un solo lugar, tal vez en una subclase de Windows personalizada para facilitar su uso. ¿Alguien tiene alguna pista sobre cómo comenzar o sobre la experiencia previa con problemas similares?


¿Por qué exactamente estás usando "muchas ventanas"? ¿Por qué no solo una ventana con un control de pestañas? ¿O una sola ventana con controles de usuario?

De todos modos, para responder a su pregunta, los controles de usuario son una forma en que desea obtener la funcionalidad que está describiendo como deficiente.

Cree una nueva clase de ventana y haga que tenga una propiedad "Childrens" que permita que un objeto se incruste en el panel de la base donde desea que vayan los "controles específicos de la ventana".

Al abrir ventanas nuevas, crea una instancia del tipo de ventana y un control de usuario con los controles específicos, agrega el control de usuario a la propiedad Niños de tu ventana y luego muestra la ventana. Incluso puede vincular manejadores de eventos, DataContexts y lo que no en este momento.


El enfoque más simple es crear WPF una "Página" para los controles específicos de la ventana y colocar un "Marco" en la ventana principal. Incluso puedes crear una buena navegación de esta manera.


Si eres lo suficientemente valiente como para asumir un gran cambio arquitectónico, podrías considerar CompositeWPF (anteriormente con el nombre en código Prism) de los chicos de Patterns & Practices en Microsoft.

De interés para usted sería la capacidad de definir "regiones" en un shell (es decir, ventana) y luego usar vistas para llenar las regiones. Utiliza el patrón Model-View-Presenter para permitir el desarrollo independiente de "vistas" del modelo que pueden reubicarse fácilmente a lo largo del tiempo, ya que el shell solo define regiones y no está acoplado directamente a lo que se le coloca. Principalmente, esto ayuda a desacoplar el caparazón de las vistas y las vistas entre sí y facilita la prueba de la unidad ... bla, bla, bla.

Es un gran salto y algo que le ralentizará para empezar, aunque su situación es uno de los tipos de aplicaciones que CompositeWPF debe abordar.

Como parte de CompositeWPF, tendrá que tener en cuenta varios patrones que pueden confundir a los recién llegados, por ejemplo, The UnityContainer, inversión de control, MVP (o Model / view / view-model) e inyección de dependencia.

Recuerdo cuando comencé con las aplicaciones de muestra que estaban desconcertadas porque no era obvio cómo se estaban creando algunas de las vistas. El contenedor de unidad instanciará objetos y llamará mágicamente a constructores parametrizados.

CompositeWPF es una solución elegante para su pregunta, pero no es simple ni directa. Habiendo utilizado CompositeWPF en mi último proyecto, tengo la intención de usarlo nuevamente para la próxima aplicación adecuada.


Puede crear un nuevo ControlTemplate que se dirija a una ventana para lograr esto como se muestra a continuación.

<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>