Panoramica delle finestre di dialogo (WPF .NET)

Windows Presentation Foundation (WPF) consente di progettare finestre di dialogo personalizzate. Le finestre di dialogo sono finestre, ma con una finalità e un'esperienza utente specifiche. Questo articolo illustra il funzionamento di una finestra di dialogo e i tipi di finestre di dialogo che è possibile creare e usare. Le finestre di dialogo vengono usate per:

  • Visualizzazione di informazioni specifiche agli utenti.
  • Raccolta delle informazioni immesse dagli utenti.
  • Visualizzazione e raccolta di informazioni.
  • Visualizzare un prompt del sistema operativo, ad esempio la finestra di stampa.
  • Selezionare un file o una cartella.

Questi tipi di finestre sono noti come finestre di dialogo. Una finestra di dialogo può essere visualizzata in due modi: modale e senza modalità.

La visualizzazione di una finestra di dialogo modale all'utente è una tecnica con cui l'applicazione interrompe l'operazione fino a quando l'utente non chiude la finestra di dialogo. In genere si tratta di un prompt o di un avviso. Altre finestre dell'applicazione non possono essere interagite finché la finestra di dialogo non viene chiusa. Una volta chiusa la finestra di dialogo modale , l'applicazione continua. Le finestre di dialogo più comuni vengono usate per visualizzare un file aperto o salvare il prompt dei file, la visualizzazione della finestra di dialogo della stampante o la messaggistica dell'utente con stato.

Una finestra di dialogo senza modalità non impedisce a un utente di attivare altre finestre mentre è aperta. Ad esempio, se un utente vuole trovare occorrenze di una determinata parola in un documento, una finestra principale apre spesso una finestra di dialogo per chiedere a un utente quale parola sta cercando. Poiché l'applicazione non vuole impedire all'utente di modificare il documento, la finestra di dialogo non deve essere modale. Una finestra di dialogo senza modalità fornisce almeno un pulsante Chiudi per chiudere la finestra di dialogo. È possibile fornire altri pulsanti per eseguire funzioni specifiche, ad esempio un pulsante Trova successivo per trovare la parola successiva in una ricerca di parole.

Con WPF è possibile creare diversi tipi di finestre di dialogo, ad esempio finestre di messaggio, finestre di dialogo comuni e finestre di dialogo personalizzate. Questo articolo illustra ogni esempio e l'esempio di finestra di dialogo fornisce esempi corrispondenti.

Finestre di messaggio

Una finestra di messaggio è una finestra di dialogo che può essere utilizzata per visualizzare informazioni di testo e consentire agli utenti di prendere decisioni con i pulsanti. La figura seguente mostra una finestra di messaggio che pone una domanda e fornisce all'utente tre pulsanti per rispondere alla domanda.

Word processor dialog box asking if you want to save the changes to the document before the application closes.

Per creare una finestra di messaggio, usare la MessageBox classe . MessageBox consente di configurare il testo della finestra di messaggio, il titolo, l'icona e i pulsanti.

Per altre informazioni, vedere Come aprire una finestra di messaggio.

Finestre di dialogo comuni

Windows implementa diversi tipi di finestre di dialogo riutilizzabili comuni a tutte le applicazioni, incluse le finestre di dialogo per la selezione di file e la stampa.

Poiché queste finestre di dialogo vengono fornite dal sistema operativo, vengono condivise tra tutte le applicazioni eseguite nel sistema operativo. Queste finestre di dialogo offrono un'esperienza utente coerente e sono note come finestre di dialogo comuni. Poiché un utente usa una finestra di dialogo comune in un'applicazione, non è necessario imparare a usare tale finestra di dialogo in altre applicazioni.

WPF incapsula il file aperto, salva file, apri cartella e stampa le finestre di dialogo comuni e le espone come classi gestite da usare.

Open file dialog box called from WPF.

Per altre informazioni sulle finestre di dialogo comuni, vedere gli articoli seguenti:

Finestre di dialogo personalizzate

Anche se le finestre di dialogo comuni sono utili e devono essere usate quando possibile, non supportano i requisiti delle finestre di dialogo specifiche del dominio. In questi casi, è necessario creare finestre di dialogo personalizzate. Come verrà illustrato in seguito, una finestra di dialogo è una finestra con particolari comportamenti. Window implementa questi comportamenti e si usa la finestra per creare finestre di dialogo modali e modeless personalizzate.

Quando si crea una finestra di dialogo personalizzata, è necessario tenere presenti molte considerazioni sulla progettazione. Sebbene sia una finestra dell'applicazione che una finestra di dialogo contengano analogie, ad esempio la condivisione della stessa classe di base, viene usata una finestra di dialogo per uno scopo specifico. In genere è necessaria una finestra di dialogo quando è necessario richiedere a un utente una sorta di informazioni o risposta. In genere l'applicazione verrà sospesa mentre viene visualizzata la finestra di dialogo (modale), limitando l'accesso al resto dell'applicazione. Una volta chiusa la finestra di dialogo, l'applicazione continua. Tuttavia, non è un requisito limitare le interazioni alla finestra di dialogo da sola.

Quando una finestra WPF viene chiusa, non può essere riaperta. Le finestre di dialogo personalizzate sono finestre WPF e si applica la stessa regola. Per informazioni su come chiudere una finestra, vedere Come chiudere una finestra o una finestra di dialogo.

Implementazione di una finestra di dialogo

Quando si progetta una finestra di dialogo, seguire questi suggerimenti per creare un'esperienza utente ottimale:

❌ NON ingombrare la finestra di dialogo. L'esperienza della finestra di dialogo consente all'utente di immettere alcuni dati o di effettuare una scelta.

✔️ Specificare un pulsante OK per chiudere la finestra.

✔️ IMPOSTARE la proprietà del IsDefault pulsante OK su true per consentire all'utente di premere INVIO per accettare e chiudere la finestra.

✔️ Prendere in considerazione l'aggiunta di un pulsante Annulla in modo che l'utente possa chiudere la finestra e indicare che non vuole continuare.

✔️ IMPOSTARE la proprietà del IsCancel pulsante Annulla su true per consentire all'utente di premere ESC per chiudere la finestra.

✔️ IMPOSTARE il titolo della finestra per descrivere in modo accurato ciò che rappresenta il dialogo o le operazioni che l'utente deve eseguire con la finestra di dialogo.

✔️ IMPOSTARE valori minimi di larghezza e altezza per la finestra, impedendo all'utente di ridimensionare la finestra troppo piccola.

✔️ È consigliabile disabilitare la possibilità di ridimensionare la finestra se ShowInTaskbar è impostata su false. È possibile disabilitare il ridimensionamento impostando su ResizeModeNoResize

Il codice seguente illustra questa configurazione.

<Window x:Class="Dialogs.Margins"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Change Margins"
        Closing="Window_Closing"
        MinHeight="200"
        MinWidth="300"
        SizeToContent="WidthAndHeight"
        ResizeMode="NoResize"
        ShowInTaskbar="False"
        WindowStartupLocation="CenterOwner" 
        FocusManager.FocusedElement="{Binding ElementName=leftMarginTextBox}">
    <Grid Margin="10">
        <Grid.Resources>
            <!-- Default settings for controls -->
            <Style TargetType="{x:Type Label}">
                <Setter Property="Margin" Value="0,3,5,5" />
                <Setter Property="Padding" Value="0,0,0,5" />
            </Style>
            <Style TargetType="{x:Type TextBox}">
                <Setter Property="Margin" Value="0,0,0,5" />
            </Style>
            <Style TargetType="{x:Type Button}">
                <Setter Property="Width" Value="70" />
                <Setter Property="Height" Value="25" />
                <Setter Property="Margin" Value="5,0,0,0" />
            </Style>
        </Grid.Resources>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>

        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition />
        </Grid.RowDefinitions>

        <!-- Left,Top,Right,Bottom margins-->
        <Label Grid.Column="0" Grid.Row="0">Left Margin:</Label>
        <TextBox Name="leftMarginTextBox" Grid.Column="1" Grid.Row="0" />

        <Label Grid.Column="0" Grid.Row="1">Top Margin:</Label>
        <TextBox Name="topMarginTextBox" Grid.Column="1" Grid.Row="1"/>

        <Label Grid.Column="0" Grid.Row="2">Right Margin:</Label>
        <TextBox Name="rightMarginTextBox" Grid.Column="1" Grid.Row="2" />

        <Label Grid.Column="0" Grid.Row="3">Bottom Margin:</Label>
        <TextBox Name="bottomMarginTextBox" Grid.Column="1" Grid.Row="3" />

        <!-- Accept or Cancel -->
        <StackPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="4" Orientation="Horizontal" HorizontalAlignment="Right">
            <Button Name="okButton" Click="okButton_Click" IsDefault="True">OK</Button>
            <Button Name="cancelButton" IsCancel="True">Cancel</Button>
        </StackPanel>
    </Grid >
</Window>

Il codice XAML precedente crea una finestra simile all'immagine seguente:

A dialog box window for WPF that shows left, top, right, bottom text boxes.

Elementi dell'interfaccia utente che aprono una finestra di dialogo

L'esperienza utente per una finestra di dialogo si estende anche nella barra dei menu o nel pulsante della finestra che lo apre. Quando una voce di menu o un pulsante esegue una funzione che richiede l'interazione dell'utente tramite una finestra di dialogo prima che la funzione possa continuare, il controllo deve usare i puntini di sospensione alla fine del testo dell'intestazione:

<MenuItem Header="_Margins..." Click="formatMarginsMenuItem_Click" />
<!-- or -->
<Button Content="_Margins..." Click="formatMarginsButton_Click" />

Quando una voce di menu o un pulsante esegue una funzione che visualizza una finestra di dialogo che non richiede l'interazione dell'utente, ad esempio una finestra di dialogo Informazioni su , non sono necessari i puntini di sospensione.

Le voci di menu sono un modo comune per fornire agli utenti azioni dell'applicazione raggruppate in temi correlati. Probabilmente è stato visualizzato il menu File in molte applicazioni diverse. In un'applicazione tipica, la voce di menu File consente di salvare un file, caricare un file e stampare un file. Se l'azione visualizzerà una finestra modale, l'intestazione include in genere i puntini di sospensione, come illustrato nell'immagine seguente:

A WPF window that shows menu items with an ellipsis to indicate which item shows a dialog box.

Due delle voci di menu hanno i puntini di sospensione: .... Ciò consente all'utente di identificare che quando selezionano tali voci di menu, viene visualizzata una finestra modale, sospendo l'applicazione fino alla chiusura dell'utente.

Questa tecnica di progettazione è un modo semplice per comunicare con gli utenti ciò che dovrebbero aspettarsi.

Pulsanti

È possibile seguire lo stesso principio descritto nella sezione Voci di menu. Usa i puntini di sospensione sul testo del pulsante per indicare che quando l'utente preme il pulsante, verrà visualizzata una finestra di dialogo modale. Nell'immagine seguente sono presenti due pulsanti ed è facile comprendere quale pulsante visualizza una finestra di dialogo:

A WPF window that shows buttons with an ellipsis to indicate which item shows a dialog box.

Restituire un risultato

Aprire un'altra finestra, in particolare una finestra di dialogo modale, è un ottimo modo per restituire lo stato e le informazioni al codice chiamante.

Quando viene visualizzata una finestra di dialogo chiamando ShowDialog(), il codice che ha aperto la finestra di dialogo attende fino a quando il ShowDialog metodo non viene restituito. Quando il metodo termina, il codice che ha chiamato deve decidere se continuare l'elaborazione o arrestare l'elaborazione. L'utente indica in genere questo aspetto premendo un pulsante OK o Annulla nella finestra di dialogo.

Quando si preme il pulsante OK , ShowDialog deve essere progettato per restituire truee il pulsante Annulla per restituire false. Questa operazione viene ottenuta impostando la DialogResult proprietà quando si preme il pulsante.

private void okButton_Click(object sender, RoutedEventArgs e) =>
    DialogResult = true;

private void cancelButton_Click(object sender, RoutedEventArgs e) =>
    DialogResult = false;
Private Sub okButton_Click(sender As Object, e As RoutedEventArgs)
    DialogResult = True
End Sub

Private Sub cancelButton_Click(sender As Object, e As RoutedEventArgs)
    DialogResult = False
End Sub

La DialogResult proprietà può essere impostata solo se la finestra di dialogo è stata visualizzata con ShowDialog(). Quando la DialogResult proprietà è impostata, la finestra di dialogo viene chiusa.

Se la proprietà di IsCancel un pulsante è impostata su truee la finestra viene aperta con ShowDialog(), la chiave ESC chiuderà la finestra e impostata su DialogResultfalse.

Per altre informazioni sulla chiusura delle finestre di dialogo, vedere Come chiudere una finestra o una finestra di dialogo.

Elaborazione della risposta

Restituisce ShowDialog() un valore booleano per indicare se l'utente ha accettato o annullato la finestra di dialogo. Se si invia un avviso all'utente a un elemento, ma non è necessario prendere una decisione o fornire dati, è possibile ignorare la risposta. È anche possibile controllare la risposta controllando la DialogResult proprietà . Il codice seguente illustra come elaborare la risposta:

var dialog = new Margins();

// Display the dialog box and read the response
bool? result = dialog.ShowDialog();

if (result == true)
{
    // User accepted the dialog box
    MessageBox.Show("Your request will be processed.");
}
else
{
    // User cancelled the dialog box
    MessageBox.Show("Sorry it didn't work out, we'll try again later.");
}
Dim marginsWindow As New Margins

Dim result As Boolean? = marginsWindow.ShowDialog()

If result = True Then
    ' User accepted the dialog box
    MessageBox.Show("Your request will be processed.")
Else
    ' User cancelled the dialog box
    MessageBox.Show("Sorry it didn't work out, we'll try again later.")
End If

marginsWindow.Show()

Finestra di dialogo senza modalità

Per visualizzare una finestra di dialogo senza modalità, chiamare Show(). La finestra di dialogo deve almeno fornire un pulsante Chiudi . È possibile fornire altri pulsanti ed elementi interattivi per eseguire una funzione specifica, ad esempio un pulsante Trova successivo per trovare la parola successiva in una ricerca di parole.

Poiché una finestra di dialogo senza modalità non impedisce al codice chiamante di continuare, è necessario fornire un modo diverso per restituire un risultato. Eseguire una delle operazioni seguenti:

  • Esporre una proprietà dell'oggetto dati nella finestra.
  • Gestire l'evento Window.Closed nel codice chiamante.
  • Creare eventi nella finestra generata quando l'utente seleziona un oggetto o preme un pulsante specifico.

Nell'esempio seguente viene utilizzato l'evento Window.Closed per visualizzare una finestra di messaggio all'utente quando la finestra di dialogo viene chiusa. Il messaggio visualizzato fa riferimento a una proprietà della finestra di dialogo chiusa. Per altre informazioni sulla chiusura delle finestre di dialogo, vedere Come chiudere una finestra o una finestra di dialogo.

var marginsWindow = new Margins();

marginsWindow.Closed += (sender, eventArgs) =>
{
    MessageBox.Show($"You closed the margins window! It had the title of {marginsWindow.Title}");
};

marginsWindow.Show();
Dim marginsWindow As New Margins

AddHandler marginsWindow.Closed, Sub(sender As Object, e As EventArgs)
                                     MessageBox.Show($"You closed the margins window! It had the title of {marginsWindow.Title}")
                                 End Sub

marginsWindow.Show()

Vedi anche