Window vs Page vs UserControl para la navegación WPF?

192

Actualmente estoy escribiendo una aplicación de escritorio, pero parece que no puedo entender qué usar al redirigir a alguien a una nueva sección de la aplicación.

Mis opciones parecen ser

  • Ventana
  • Página
  • Control de usuario

pero no entiendo cuál es la diferencia entre ellos y cuándo debería usar cada uno.

¿Podría alguien explicarme las diferencias y dar un ejemplo de para qué situaciones / aplicaciones puede usar cada una?

Steve
fuente

Respuestas:

337

Un objeto Window es exactamente lo que parece: es nuevo Windowpara su aplicación. Debe usarlo cuando desee abrir una ventana completamente nueva. No suelo usar más de unoWindow en WPF porque prefiero poner contenido dinámico en mi ventana principal que cambia según la acción del usuario.

Una página es una página dentro de su ventana. Se utiliza principalmente para sistemas basados ​​en la web como XBAP, donde tiene una sola ventana del navegador y se pueden alojar diferentes páginas en esa ventana. También se puede usar en aplicaciones de navegación como sellmeadog, dijo .

Un UserControl es un control reutilizable creado por el usuario que puede agregar a su IU de la misma manera que agregaría cualquier otro control. Por lo general, creo un UserControlcuando quiero incorporar alguna funcionalidad personalizada (por ejemplo, a CalendarControl), o cuando tengo una gran cantidad de código XAML relacionado, como Viewcuando uso el patrón de diseño MVVM.

Al navegar entre ventanas, simplemente puede crear un nuevo Windowobjeto y mostrarlo

var NewWindow = new MyWindow();
newWindow.Show();

pero como dije al comienzo de esta respuesta, prefiero no administrar varias ventanas si es posible.

Mi método preferido de navegación es crear un área de contenido dinámico usando a ContentControl, y llenarla con un UserControlcontenido cualquiera sea la vista actual.

<Window x:Class="MyNamespace.MainWindow" ...>
    <DockPanel>
        <ContentControl x:Name="ContentArea" />
    </DockPanel>
</Window>

y en su evento de navegación simplemente puede configurarlo usando

ContentArea.Content = new MyUserControl();

Pero si está trabajando con WPF, le recomiendo el patrón de diseño MVVM. Tengo un ejemplo muy básico en mi blog que ilustra cómo navegarías usando MVVM, usando este patrón:

<Window x:Class="SimpleMVVMExample.ApplicationView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:SimpleMVVMExample"
        Title="Simple MVVM Example" Height="350" Width="525">

   <Window.Resources>
      <DataTemplate DataType="{x:Type local:HomeViewModel}">
         <local:HomeView /> <!-- This is a UserControl -->
      </DataTemplate>
      <DataTemplate DataType="{x:Type local:ProductsViewModel}">
         <local:ProductsView /> <!-- This is a UserControl -->
      </DataTemplate>
   </Window.Resources>

   <DockPanel>
      <!-- Navigation Buttons -->
      <Border DockPanel.Dock="Left" BorderBrush="Black"
                                    BorderThickness="0,0,1,0">
         <ItemsControl ItemsSource="{Binding PageViewModels}">
            <ItemsControl.ItemTemplate>
               <DataTemplate>
                  <Button Content="{Binding Name}"
                          Command="{Binding DataContext.ChangePageCommand,
                             RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
                          CommandParameter="{Binding }"
                          Margin="2,5"/>
               </DataTemplate>
            </ItemsControl.ItemTemplate>
         </ItemsControl>
      </Border>

      <!-- Content Area -->
      <ContentControl Content="{Binding CurrentPageViewModel}" />
   </DockPanel>
</Window>

Captura de pantalla1 Captura de pantalla2

Rachel
fuente
Tengo una pregunta, MVVM de lo que puedo decir parece funcionar bien con los conjuntos de datos, pero ¿qué pasa con los formularios estáticos como, por ejemplo, un formulario de entrada para una auditoría? ¿Debo usar una página o control de usuario para páginas estáticas?
Herrozerro
2
@Herrozerro Si quisiera hacer un formulario de Auditoría usando MVVM, tendría un que AuditViewModelcontiene todos los datos y la funcionalidad del formulario, y lo dibujaría usando un AuditViewUserControl, o simplemente unDataTemplate
Rachel
1
¡Gracias! En realidad, después de revisar su blog y algunos otros sitios, entiendo mejor cómo funciona MVVM.
Herrozerro
1
@Herrozerro The ViewModelgeneralmente se crea para View, mientras que Modelsson los objetos de datos y las clases ("bloques de construcción") utilizados por su aplicación ( ViewModels)
Rachel
1
@ GTS13 Sí, lo hago con frecuencia. Ato TabControl.ItemsSourcea una colección de objetos y uso DataTemplates para decirle a WPF cómo dibujar cada tipo de objeto en cada pestaña. Por lo general, algo como esto
Rachel
13
  • La ventana es como Windows.Forms.Formuna nueva ventana
  • La página es, de acuerdo con la documentación en línea :

    Encapsula una página de contenido que Windows Internet Explorer, NavigationWindow y Frame pueden navegar y alojar.

    Así que básicamente usas esto si vas a visualizar contenido HTML

  • UserControl es para casos en los que desea crear algún componente reutilizable (pero no uno independiente) para usarlo en múltiples diferentesWindows

Tigran
fuente
Gracias por su respuesta. Entonces, por ejemplo, si estuviera creando una aplicación que tuviera botones a la izquierda pero quisiera ver el contenido dentro de estos botones en el lado derecho, ¿usaría un control de usuario?
Steve
@Steve: use UserControlen caso de que piense que el mismo conjunto de controles que usará en esta ventana también lo usará en otro, así que en lugar de escribir un código doble, simplemente cree un UserControl, pero si no, simplemente coloque controles para la visualización de sus datos en Windowsí mismo, en el lado derecho de los botones que mencionó.
Tigran
66
Hay un elemento más que creo que hay que añadir: DataTemplates. Estos se usan cuando desea decirle a WPF cómo dibujar un elemento dentro de un alcance específico. Por ejemplo, si desea dibujar sus Buttonscírculos redondos, simplemente puede usar a en DataTemplatelugar de a UserControl. Usualmente lo uso UserControlscuando quiero un nuevo control con su propia funcionalidad, o cuando tengo mucho XAML para un solo componente, como para un View. Para bits más pequeños de XAML que no requieren ninguna funcionalidad especial, debe usar un en DataTemplatelugar de crear unUserControl
Rachel
3
En general, el contenido de a Pageno es HTML sino XAML. Sin embargo, a Pageestá vinculado al marco de navegación que es conceptualmente similar a cómo se realiza la navegación en un navegador web. (Y las páginas incluso se pueden alojar en un navegador si la aplicación es una aplicación XBAP.)
Martin Liversage
6

Todo depende de la aplicación que intentes crear. Use Windows si está creando una aplicación basada en diálogo. Use Pages si está creando una aplicación basada en navegación . UserControls será útil independientemente de la dirección que vaya, ya que puede usarlos tanto en Windows como en Pages.

Un buen lugar para comenzar a explorar es aquí: http://windowsclient.net/learn

vender
fuente
5

Usualmente usamos One Main Windowpara la aplicación y otras ventanas se pueden usar en situaciones como cuando necesita ventanas emergentes porque en lugar de usar controles emergentes en XAML que no son visibles, podemos usar una ventana que sea visible en el momento del diseño para que sea fácil trabajar con

Por otro lado, usamos muchas páginas para navegar de una pantalla a otra, como la pantalla de administración de usuarios a la pantalla de pedidos, etc. En la ventana principal podemos usar el Framecontrol para la navegación como debajo de XAML

    <Frame Name="mainWinFrame" NavigationUIVisibility="Hidden"  ButtonBase.Click="mainWinFrame_Click">
    </Frame>

C#

     private void mainWinFrame_Click(object sender, RoutedEventArgs e)
    {
        try
        {
            if (e.OriginalSource is Button)
            {
                Button btn = (Button)e.OriginalSource;

                if ((btn.CommandParameter != null) && (btn.CommandParameter.Equals("Order")))
                {

                    mainWinFrame.Navigate(OrderPage);
                }
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "Error");
        }
    }

Esa es una forma de hacerlo. También podemos usar un Control de pestañas en lugar de Fram y Agregar páginas usando un Diccionario mientras agregamos una nueva página, verifique si el control ya existe y solo navegue, de lo contrario agregue y navegue. Espero que eso ayude a alguien

dnxit
fuente