Window vs Page vs UserControl per la navigazione WPF?


192

Attualmente sto scrivendo un'applicazione desktop, ma non riesco a capire cosa usare quando si reindirizza qualcuno a una nuova sezione dell'applicazione.

Le mie opzioni sembrano essere

  • Finestra
  • Pagina
  • UserControl

ma non capisco quale sia la differenza tra loro e quando dovrei usarli.

Qualcuno potrebbe spiegare le differenze per me e dare un esempio di quali situazioni / applicazioni potresti usare ognuna?

Risposte:


338

Un oggetto Window è proprio quello che sembra: è un nuovo Windowper la tua applicazione. Dovresti usarlo quando vuoi far apparire una finestra completamente nuova. Spesso non ne uso più di uno Windowin WPF perché preferisco inserire contenuto dinamico nella mia finestra principale che cambia in base all'azione dell'utente.

Una pagina è una pagina all'interno della tua finestra. Viene utilizzato principalmente per sistemi basati sul Web come un XBAP, in cui si dispone di un'unica finestra del browser e in quella finestra è possibile ospitare pagine diverse. Può essere utilizzato anche in applicazioni di navigazione come ha detto sellmeadog .

Un UserControl è un controllo riutilizzabile creato dall'utente che puoi aggiungere all'interfaccia utente nello stesso modo in cui aggiungeresti qualsiasi altro controllo. Di solito creo un UserControlquando voglio incorporare alcune funzionalità personalizzate (ad esempio, a CalendarControl) o quando ho una grande quantità di codice XAML correlato, come ad esempio Viewquando uso il modello di progettazione MVVM.

Durante la navigazione tra le finestre, è possibile semplicemente creare un nuovo Windowoggetto e mostrarlo

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

ma come ho detto all'inizio di questa risposta, preferisco non gestire più finestre se possibile.

Il mio metodo di navigazione preferito è quello di creare un'area di contenuto dinamico usando a ContentControle popolarla con un UserControlcontenuto qualunque sia la vista corrente.

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

e nel tuo evento di navigazione puoi semplicemente impostarlo usando

ContentArea.Content = new MyUserControl();

Ma se lavori con WPF, consiglio vivamente il modello di progettazione MVVM. Ho un esempio molto semplice sul mio blog che illustra come navigheresti usando MVVM, usando questo schema:

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

screenshot1 screenshot2


Ho una domanda, MVVM da quello che posso dire sembra funzionare bene con i set di dati, ma per quanto riguarda i moduli statici come ad esempio un modulo di iscrizione per un audit. Dovrei usare una pagina o un controllo utente per le pagine statiche?
Herrozerro,

2
@Herrozerro Se volessi creare un modulo di Audit usando MVVM, avrei un AuditViewModelcontenente tutti i dati e le funzionalità del modulo e lo disegnerei usando un AuditViewUserControl, o semplicemente unDataTemplate
Rachel

1
Grazie! In realtà dopo aver esaminato il tuo blog e alcuni altri siti, ho una migliore comprensione di come funziona MVVM.
Herrozerro,

1
@Herrozerro The ViewModelè in genere creato per View, mentre Modelssono gli oggetti dati e le classi ("blocchi") utilizzati dall'applicazione ( ViewModels)
Rachel,

1
@ GTS13 Sì, lo faccio spesso. Mi legano la TabControl.ItemsSourcea una collezione di oggetti e l'uso DataTemplates dire WPF come disegnare ogni tipo di oggetto in ogni scheda. Di solito qualcosa di simile a questa
Rachel

13
  • La finestra è come Windows.Forms.Form, quindi solo una nuova finestra
  • La pagina è, secondo la documentazione online :

    Incapsula una pagina di contenuto che può essere navigata e ospitata da Windows Internet Explorer, NavigationWindow e Frame.

    Quindi sostanzialmente lo usi se visualizzi del contenuto HTML

  • UserControl è per i casi in cui si desidera creare un componente riutilizzabile (ma non uno autonomo) per utilizzarlo in piùWindows


La ringrazio per la risposta. Quindi, ad esempio, se stavi costruendo un'app con i pulsanti a sinistra ma volessi vedere il contenuto all'interno di questi pulsanti sul lato destro, useresti un controllo utente?
Steve,

@Steve: usa UserControlnel caso in cui pensi che lo stesso set di controlli che userai in questa finestra lo userai anche su qualcun altro, quindi invece di scrivere un doppio codice, basta creare un UserControl, ma in caso contrario, basta mettere i controlli per la visualizzazione di i tuoi dati su Windowse stesso, sul lato destro dai pulsanti che hai menzionato.
Tigran,

6
C'è un altro elemento che secondo me dovrebbe essere aggiunto: DataTemplates. Vengono utilizzati quando si desidera indicare a WPF come disegnare un oggetto in un ambito specifico. Ad esempio, se volessi disegnare i tuoi Buttonscerchi rotondi, potresti semplicemente usare un DataTemplateinvece di un UserControl. Di solito lo uso UserControlsquando voglio un nuovo controllo con le sue funzionalità, o quando ho un sacco di XAML per un singolo componente, come per un View. Per i bit più piccoli di XAML che non richiedono alcuna funzionalità speciale, è necessario utilizzare un DataTemplateinvece di creare unUserControl
Rachel

3
In generale, il contenuto di a Pagenon è HTML ma XAML. Tuttavia, a Pageè legato al framework di navigazione che è concettualmente simile a come viene eseguita la navigazione in un browser web. (E le pagine possono anche essere ospitate in un browser se l'applicazione è un'applicazione
XBAP

6

Tutto dipende dall'app che stai cercando di creare. Usa Windows se stai costruendo un'app basata su finestre di dialogo. Usa Pages se stai costruendo un'app basata sulla navigazione . UserControls sarà utile indipendentemente dalla direzione in cui vai, dato che puoi usarli sia in Windows che in Pages.

Un buon posto per iniziare ad esplorare è qui: http://windowsclient.net/learn


5

Di solito utilizziamo One Main Windowper l'applicazione e altre finestre possono essere utilizzate in situazioni come quando hai bisogno di popup perché invece di usare i controlli popup in XAML che non sono visibili possiamo usare una finestra che è visibile in fase di progettazione in modo che sia facile lavorare con

d'altra parte usiamo molte pagine per navigare da una schermata all'altra come la schermata Gestione utenti per ordinare la schermata ecc. Nella finestra principale possiamo usare il Framecontrollo per la navigazione come sotto 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");
        }
    }

Questo è un modo per farlo Possiamo anche usare un controllo Tab invece di Fram e aggiungere pagine ad esso usando un dizionario mentre aggiungi una nuova pagina controlla se il controllo esiste già, quindi naviga solo altrimenti aggiungi e naviga. Spero che possa aiutare qualcuno


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.