TOC

This article is currently in the process of being translated into Russian (~46% done).

UserControls & CustomControls:

Creating & using a UserControl

Пользовательские элементы управления представленны в WPF классом UserControl. Принцип состоит в группировке разметки и кода в контейнер для повторного использования. Таким образом тот же интерфейс с той же функциональностью может быть использован в нескольких разных местах и даже в нескольких приложениях.

Пользовательский элемент управления функционирует совершенно таким же образом, как и окно (Window) WPF - поле, где размещаются другие органы управления и файл кода, где происходит взаимодействие этих органов управления. Файл, который содержит пользовательский элемент управления, имеет расширение .xaml, а файл кода - расширение .xaml.cs - точно так же, как и Window. Хотя начало файла разметки выглядит несколько иначе:

<UserControl x:Class="WpfTutorialSamples.User_Controls.LimitedInputUserControl"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
     mc:Ignorable="d"
     d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
   
    </Grid>
</UserControl>

Впрочем, ничего необычного: в корне вместо Window стоит UserControl, затем свойства DesignHeight и DesignWidth, задающие размер пользовательского элемента на момент проектирования (в рантайме размер будет зависеть от родительского контейнера). Аналогичную вещь можно найти в Code-behind, где просто наследуется UserControl вместо Window.

Создаём User Control

Добавьте пользовательский элемент управления к вашему проекту так же, как вы добавляли бы Window: кликните правой кнопкой по папке проекта, в который хотите добавить его, как проиллюстрировано на этом скриншоте (меню может выглядеть несколько иначе в зависимости от версии Visual Studio).

В этой статье мы создадим полезный контрол, позволяющий ограничить число символов, которые пользователь будет вводить в TextBox. Мы так же будем показывать пользователю, сколько символов уже затрачено из общего числа. Это очень легко сделать и используется во многих веб-приложениях, таких как Twitter. Было бы проще добавить эту функцию обычному Окну, но поскольку она может пригодиться в различных местах в вашем приложении, имеет смысл обернуть её в UserControl для повторного использования.

Прежде чем мы углубимся в код, давайте посмотрим на конечный результат который мы хотим получить:

Вот, собственно, код нашего контрола:

<UserControl x:Class="WpfTutorialSamples.User_Controls.LimitedInputUserControl"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
     mc:Ignorable="d"
     d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
<Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    <RowDefinition Height="*" />
</Grid.RowDefinitions>      
<Grid.ColumnDefinitions>
    <ColumnDefinition Width="*" />
    <ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Content="{Binding Title}" />
<Label Grid.Column="1">
    <StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding ElementName=txtLimitedInput, Path=Text.Length}" />
<TextBlock Text="/" />
<TextBlock Text="{Binding MaxLength}" />
    </StackPanel>
</Label>
<TextBox MaxLength="{Binding MaxLength}" Grid.Row="1" Grid.ColumnSpan="2" Name="txtLimitedInput" ScrollViewer.VerticalScrollBarVisibility="Auto" TextWrapping="Wrap" />
    </Grid>
</UserControl>
using System;
using System.Windows.Controls;

namespace WpfTutorialSamples.User_Controls
{
    public partial class LimitedInputUserControl : UserControl
    {
public LimitedInputUserControl()
{
    InitializeComponent();
    this.DataContext = this;
}

public string Title { get; set; }

public int MaxLength { get; set; }
    }
}

The markup is pretty straight forward: A Grid, with two columns and two rows. The upper part of the Grid contains two labels, one showing the title and the other one showing the stats. Each of them use data binding for all of the information needed - the Title and MaxLength comes from the Code-behind properties, which we have defined in as regular properties on a regular class.

The current character count is obtained by binding to the Text.Length property directly on the TextBox control, which uses the lower part of the user control. The result can be seen on the screenshot above. Notice that because of all these bindings, we don't need any C# code to update the labels or set the MaxLength property on the TextBox - instead, we just bind directly to the properties.

Consuming/using the User Control

With the above code in place, all we need is to consume (use) the User control within our Window. We'll do that by adding a reference to the namespace the UserControl lives in, in the top of the XAML code of your Window:

xmlns:uc="clr-namespace:WpfTutorialSamples.User_Controls"

After that, we can use the uc prefix to add the control to our Window like it was any other WPF control:

<uc:LimitedInputUserControl Title="Enter title:" MaxLength="30" Height="50" />

Notice how we use the Title and MaxLength properties directly in the XAML. Here's the full code sample for our window:

<Window x:Class="WpfTutorialSamples.User_Controls.LimitedInputSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:uc="clr-namespace:WpfTutorialSamples.User_Controls"
Title="LimitedInputSample" Height="200" Width="300">
    <Grid Margin="10">
<Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    <RowDefinition Height="*" />
</Grid.RowDefinitions>

<uc:LimitedInputUserControl Title="Enter title:" MaxLength="30" Height="50" />
<uc:LimitedInputUserControl Title="Enter description:" MaxLength="140" Grid.Row="1" />

    </Grid>
</Window>

With that, we can reuse this entire piece of functionality in a single line of code, as illustrated in this example where we have the limited text input control two times. As already shown, the final result looks like this:

Summary

Placing commonly used interfaces and functionality in User Controls is highly recommended, and as you can see from the above example, they are very easy to create and use.

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!