TOC

This article has been localized into Italian by the community.

Dialogs:

Creare un dialog di input personalizzato

Negli ultimi due articoli, abbiamo considerato l'uso dei dialog prefatti in WPF, ma creare il proprio è altrettanto semplice. Infatti si deve solo creare una finestra, metterci i controlli richiesti e poi mostrarla.

Tuttavia, ci sono alcune cose che dovresti ricordare quando crei finestre di dialogo, per assicurarti che l'applicazione funzioni come altre applicazioni Windows. In questo articolo creeremo una finestra di dialogo molto semplice per porre all'utente una domanda e poi restituire la risposta, discutendo le varie buone pratiche che dovrebbe seguire.

Disegnare il dialog

Per questo particolare dialog, volevo una Label che richiedesse all'utente le informazioni di cui necessitavo, un TextBox per immettere le risposte e poi i classici pulsanti Ok e cancella. Ho deciso anche di aggiungere un'icona al dialog, per migliorare l'aspetto. Questo è il risultato finale:

E qui c'è il codice per il dialog:

<Window x:Class="WpfTutorialSamples.Dialogs.InputDialogSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Input" SizeToContent="WidthAndHeight" WindowStartupLocation="CenterScreen"
        ContentRendered="Window_ContentRendered">
    <Grid Margin="15">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <Image Source="/WpfTutorialSamples;component/Images/question32.png" Width="32" Height="32" Grid.RowSpan="2" Margin="20,0" />

        <Label Name="lblQuestion" Grid.Column="1">Question:</Label>
        <TextBox Name="txtAnswer" Grid.Column="1" Grid.Row="1" MinWidth="250">Answer</TextBox>

        <WrapPanel Grid.Row="2" Grid.ColumnSpan="2" HorizontalAlignment="Right" Margin="0,15,0,0">
            <Button IsDefault="True" Name="btnDialogOk" Click="btnDialogOk_Click" MinWidth="60" Margin="0,0,10,0">_Ok</Button>
            <Button IsCancel="True" MinWidth="60">_Cancel</Button>
        </WrapPanel>
    </Grid>
</Window>
using System;
using System.Windows;

namespace WpfTutorialSamples.Dialogs
{
	public partial class InputDialogSample : Window
	{
		public InputDialogSample(string question, string defaultAnswer = "")
		{
			InitializeComponent();
			lblQuestion.Content = question;
			txtAnswer.Text = defaultAnswer;
		}

		private void btnDialogOk_Click(object sender, RoutedEventArgs e)
		{
			this.DialogResult = true;
		}

		private void Window_ContentRendered(object sender, EventArgs e)
		{
			txtAnswer.SelectAll();
			txtAnswer.Focus();
		}

		public string Answer
		{
			get { return txtAnswer.Text; }
		}
	}
}

Il codice è abbastanza semplice, ma ci sono delle cose a cui si deve prestare speciale attenzione:

XAML

Nella parte XAMLho usato un Grid come layout dei controlli, nulla di speciale in questo. Ho rimosso le proprietà Width e Height della finestra e invece le ho impostate che si adattassero al contenuto in automatico: ha senso fare così in un dialog, così che non si debba aggiustare la dimensione per fare in modo che tutto stia a posto. Invece usate i margini e le dimensioni minime per assicurarvi che le cose risultino nel modo in cui le volete, pur permettendo all'utente di ridimensionare il dialog.

Un'altra proprietà che ho cambiato sulla finestra è la proprietà WindowStartupLocation. Per un dialog di questo tipo, e probabilmente per la maggior parte delle altre finestre non principali, si dovrebbe modificare il suo valore a CenterScreen o CenterOwner, in modo da cambiare il suo comportamento di default nel quale la finestra apparirebbe in una posizione decisa da Windows, a meno che non si specifichino manualmente le sue proprietà Top e Left.

Inoltre, si presti particolare attenzione alle due proprietà che ho usato sui pulsanti del dialog: IsCancel e IsDefault. IsCancel dice a WPF che se l'utente clicca questo pulsante, il DialogResult della finestra dovrebbe essere impostato su false che farà anche in modo che la finestra si chiuda. Questo assicura anche che l'utente possa premere il tasto Esc sulla tastiera per chiudere la finestra, un'opzione che dovrebbe essere sempre possibile in un dialog Windows.

La proprietà IsDefault sposta l'attenzione sul pulsante Ok e inoltre assicura che se l'utente preme Enter sulla sua tastiera, questo pulsante sia attivato. Si necessita di un event handler per impostare il DialogResult per questa operazione, come descritto più avanti.

Code-behind

Nel Code-behind, ho cambiato il costruttore in modo che accettasse due parametri, di cui uno opzionale. Questo permette di mettere nei controlli della UI designati, le domande e risposte di default, se fornite.

Il pulsante Ok ha un event handler associato che fa in modo che la proprietà speciale DialogResult della finestra venga impostata a true quando viene cliccato, per segnalare a chi ha avviato il dialog che l'utente ha accettato il valore inserito. Non c'è un pulsante Cancella qui, perche WPF lo gestisce al posto nostro quando si imposta la proprietà IsCancel a true, come descritto sopra.

Per dare il Focus al TextBox dopo aver mostrato la finestra di dialogo, mi sono iscritto all'evento ContentRendered , dove seleziono tutto il testo nel controllo e quindi do il Focus. Se avessi voluto solamente dare il Focus, avrei potuto usare la proprietà associata FocusManager.FocusedElement sulla finestra, ma in questo caso, voglio anche selezionare il testo, per consentire all'utente di sovrascrivere immediatamente la risposta fornita di default (se presente).

Un ultimo dettaglio è la proprietà Answer che ho implementato. Semplicemente dà accesso al valore inserito del controllo TextBox, è una buona pratica per fornire una proprietà con i valori restituiti della finestra di dialogo, invece di accedere direttamente ai controlli dall'esterno della finestra. Anche questo ti consente di influenzare il valore di ritorno prima di restituirlo, se necessario.

Utilizzare il dialog

Con tutto quanto sopra a posto, siamo ora pronti per utilizzare effettivamente la nostra finestra di dialogo. È un compito molto semplice, quindi ho creato una piccola applicazione per testarlo.      Ecco il codice:

<Window x:Class="WpfTutorialSamples.Dialogs.InputDialogAppSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="InputDialogAppSample" Height="150" Width="300">
    <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
        <TextBlock>Hello, world. My name is:</TextBlock>
        <TextBlock Name="lblName" Margin="0,10" TextAlignment="Center" FontWeight="Bold">[No name entered]</TextBlock>
        <Button Name="btnEnterName" Click="btnEnterName_Click">Enter name...</Button>
    </StackPanel>
</Window>
using System;
using System.Windows;

namespace WpfTutorialSamples.Dialogs
{
	public partial class InputDialogAppSample : Window
	{
		public InputDialogAppSample()
		{
			InitializeComponent();
		}

		private void btnEnterName_Click(object sender, RoutedEventArgs e)
		{
			InputDialogSample inputDialog = new InputDialogSample("Please enter your name:", "John Doe");
			if(inputDialog.ShowDialog() == true)
				lblName.Text = inputDialog.Answer;
		}
	}
}

Non c'è niente di speciale: solo un paio di controlli TextBlock e un pulsante per richiamare la finestra di dialogo. Nel gestore di eventi Click, istanziamo la finestra InputDialogSample , fornendo una domanda e una risposta predefinita, e quindi usiamo il metodo ShowDialog () per mostrarlo - dovresti usare sempre il metodo ShowDialog () e non solo Show () per una finestra di dialogo modale come questa.

Se il risultato della finestra di dialogo è vero, nel senso che l'utente ha attivato il pulsante Ok facendo clic su di esso o premendo Invio, il risultato viene assegnato al nome Label. Questo è tutto ciò che c'è da fare!


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!