TOC

This article has been localized into Ukrainian by the community.

Діалогові вікна:

Створення користувацьких діалогових вікон

В останніх статтях ми переглянули застосування вбудованих у WPF вікон. Однак створення власних нічим не важче. Насправді вам просто слід створити вікно, помістити в нього потрібні елементи керування та показати його.

Проте є кілька речей, про які потрібно пам'ятати при створенні діалогових вікон, щоб переконатися у тому, що ваш застосунок буде поводитись, як інші застосунки Windows. У цій статті ми створимо дуже просте діалогове вікно, для того, щоб показати вам процес створення. Наше вікно призначене для того, щоб задати користувачу питання, а потім показати відповідь.

Проектування діалогового вікна

Для цього особливого діалогового вікна мені потрібен лише Label, що повідомляє користувачу, яку інформацю від нього треба дізнатися, TextBox для введення відповіді та кнопки "Ok " і "Cancel ". Крім того я вирішив додати іконку для кращого зовнішнього вигляду. Ось результат:

Ось код діалогового вікна:

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

Код дуже простий, але тут є прийоми, на які потрібно звернути особливу увагу:

XAML розмітка

У XAML частині я використав Grid в якості макет для елементів керування. Я прибрав значення властивостей Width та Height вікна. Тепер вони встановлюються автоматично на основі вмісту вікна, що чудово підходить для діалогових вікон. Адже вам не потрібно вручну змінювати розмір вікна в залежності від введеного тексту. Натомість використайте властивості Margin та Minimum Size, щоб переконатися у тому, що все виглядає як вам треба.

Інша властивість вікна, яку я змінив - це WindowStartupLocation. Для подібних діалогових вікон та й загалом для неосновних вікон вам слід змінити значення на CenterScreen або CenterOwner. Таким чином ви змінете поведінку за умовчуванням, при якій початкову позицію вашого вікна визначає Windows, якщо ви вручну не задасте значення властивостей Top та Left.

Крім того зверніть особливу увагу на дві властивості, які я використав для кнопок: IsCancel та IsDefault. IsCancel повідомляє WPF про те, що користувач натиснув на цю кнопку, а отже властивість DialogResult вікна повинна отримати значення false, крім того слід закрити вікно. Крім того завдяки цьому користувач отримує змогу натиснути клавішу Esc, щоб закрити вікно.

Властивість IsDefault повертає стан фокусу кнопки "Ok". Крім того завдяки ній користувач може активувати цю кнопку, натиснувши клавішу Enter. Однак для того, щоб встановити значення DialogResult потрібен обробник подій, про який буде написано пізніше.

С# код

В С# коді я змінив конструктор так, щоб він приймав 2 параметри, один з яких необов'язковий. Таким чином можна вибрати запитання та відповідь за умовчуванням.

Кнопка "Ok " має обробник подій, що забезпечує те, що властивість DialogResult вікна отримає значення true при натиску. Таким чином діалогове вікно дізнається про те, що користувач прийняв введену ним відповідь. Нам не потрібен обробник подій для кнопки "Cancel", тому що WPF обробляє їх за нас, коли ми встановлюємо значення true властивості IsCancel, як описано вище.

Щоб сфокусуватися на елементі TextBox при показі вікна, я підписався на подію ContentRendered. Де я виділив весь текст в елементі керування та сфокусувався на ньому. Якби я просто хотів сфосуватися, то я використав би прив'язану властивість вікна, під назвою FocusManager.FocusedElement. Але в цьому випадку я також хотів виділити текст, щоб дозволити користувачу з легкістю переписати відповідь за умовчуванням (якщо така є).

Остання важлива деталь - це властивість Answer. Вона просто надає доступ до значення, введеного у елемент TextBox. Краще створити властивість, що повертає результат діалогового вікна, ніж напряму звертатися до елементів вікна. Крім того завдяки цьому можна редагувати значення перед тим, як повернути його, якщо це потрібно.

Використання діалогового вікна

Тепер ми нарешті можемо використовувати наше діалогове вікно. Це дуже просте завдання, для виконання якого я створив простенький застосунок. Ось код:

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

Тут немає нічого особливого. Просто кілька елементів TextBlock та кнопка для виклику діалогового вікна. В обробнику події Click ми створюємо екземпляр вікна InputDialogSample, що містить запитання та відповідь за умовчуванням. Після цього слід викликати метод ShowDialog(), щоб показати це вікно (ні в якому разі не використовуйте для цього метод Show()):

Якщо результатом діалогово вікна є значення True, то це значить, що користувач натиснув кнопку "Ok ". Результат залежить від тексту елементу Label. Ось і все!


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!