Lektsia_4_Elementy_upravlenia

Содержание

Слайд 2

Обзор элементов управления и их свойств

Чтобы как-то взаимодействовать с пользователем, получать от

Обзор элементов управления и их свойств Чтобы как-то взаимодействовать с пользователем, получать
пользователя ввод с клавиатуры или мыши и использовать введенные данные в программе, нам нужны элементы управления. WPF предлагает нам богатый стандартный набор элементов управления
Все элементы управления могут быть условно разделены на несколько подгрупп:
Элементы управления содержимым, например кнопки (Button), метки (Label)
Специальные контейнеры, которые содержат другие элементы, но в отличие от элементов Grid или Canvas не являются контейнерами компоновки - ScrollViewer,GroupBox
Декораторы, чье предназначение создание определенного фона вокруг вложенных элементов, например, Border или Viewbox.
Элементы управления списками, например, ListBox, ComboBox.
Текстовые элементы управления, например, TextBox, RichTextBox.
Элементы, основанные на диапазонах значений, например, ProgressBar, Slider.
Элементы для работ с датами, например, DatePicker и Calendar.
Остальные элементы управления, которые не вошли в предыдущие подгруппы, например, Image.

Слайд 3

Все элементы управления наследуются от общего класса System.Window.Controls.Control и имеют ряд общих свойств. А

Все элементы управления наследуются от общего класса System.Window.Controls.Control и имеют ряд общих
общую иерархию элементов управления можно представить следующим образом:
Вкратце рассмотрим, что представляют все эти типы в иерархии.
System.Windows.DependencyObject
Наследование от этого класса позволяет взаимодействовать с элементами в приложении через их специальную модель свойств, которые называются свойствами зависимостей (dependency properties). Эта модель упрощает применение ряда особенностей WPF, например, привязки данных. Так, система свойств зависимостей отслеживает зависимости между значениями свойств, автоматически проверяет их и изменяет при изменении зависимости.
System.Windows.Media.Visual
Класс Visual содержит инструкции, которые отвечают за отрисовку, визуализацию объекта.
System.Windows.UIElement
Класс UIElement добавляет возможности по компоновке элемента, обработку событий и получение ввода.

Слайд 4

System.Windows.Controls.Control
Класс Control представляет элемент управления, с которым взаимодействует пользователь. Этот класс добавляет

System.Windows.Controls.Control Класс Control представляет элемент управления, с которым взаимодействует пользователь. Этот класс
ряд дополнительных свойств для поддержки элементами шрифтов, цветов фона, шрифта, а также добавляет поддержку шаблонов - специального механизма в WPF, который позволяет изменять стандартное представление элемента, кастомизировать его.
И далее от класса Control наследуются непосредственно конкретные элементы управления или их базовые классы, которые получают весь функционал, добавляемый к типам в этой иерархии классов.
System.Windows.FrameworkElement
Класс FrameworkElement добавляет поддержку привязки данных, анимации, стилий. Также добавляет ряд свойств, связанных с компоновкой (выравнивание, отступы) и ряд других.
Рассмотрим некоторые из основных свойств, которые наследуются элементами управления.

Слайд 5

Name
Данное свойство определяет имя элемента управления, через которое впоследствии можно будет обращаться

Name Данное свойство определяет имя элемента управления, через которое впоследствии можно будет
к данному элементу, как в коде, так и в xaml разметке. Например, в xaml-коде у нас определена следующая кнопка:
Здесь у нас задан атрибут Click с названием метода обработчика button1_Click, который будет определен в файле кода C# и будет вызываться по нажатию кнопки. Тогда в связанном файле кода C# мы можем обратиться к этой кнопке:
Поскольку свойство Name имеет значение button1, то через это значение мы можем обратиться к кнопке в коде.

Слайд 6

FieldModifier
Свойство FieldModifier задает модификатор доступа к объекту:
В качестве значения используются стандартные модификатора

FieldModifier Свойство FieldModifier задает модификатор доступа к объекту: В качестве значения используются
доступа языка C#: private, protected, internal, protected internal и public. В данном случае объявление кнопок с модификаторами будет равноценно следующему их определению в коде:
Если для элемента не определен атрибут x:FieldModifier, то по умолчанию он равен "protected internal".

Слайд 7

Visibility
Это свойство устанавливает параметры видимости элемента и может принимать одно из трех

Visibility Это свойство устанавливает параметры видимости элемента и может принимать одно из
значений:
Visible - элемент виден и участвует в компоновке.
Collapsed - элемент не виден и не участвует в компоновке.
Hidden - элемент не виден, но при этом участвует в компоновке.
Различия между Collapsed и Hidden можно продемонстрировать на примере:

Слайд 8

Свойства настройки шрифтов
FontFamily - определяет семейство шрифта (например, Arial, Verdana и т.д.)
FontSize - определяет

Свойства настройки шрифтов FontFamily - определяет семейство шрифта (например, Arial, Verdana и
высоту шрифта
FontStyle - определяет наклон шрифта, принимает одно из трех значений - Normal, Italic,Oblique.
FontWeight - определяет толщину шрифта и принимает ряд значений, как Black,Bold и др.
FontStretch - определяет, как будет растягивать или сжимать текст, например, значение Condensed сжимает текст, а Expanded - расстягивает.
Например:
Cursor
Это свойство позволяет нам получить или установить курсор для элемента управления в одно из значений, например, Hand, Arrow, Wait и др. Например, установка курсора в коде c#: button1.Cursor=Cursors.Hand;

Слайд 9

FlowDirection
Данное свойство задает направление текста. Если оно равно RightToLeft, то текст начинается

FlowDirection Данное свойство задает направление текста. Если оно равно RightToLeft, то текст
с правого края, если - LeftToRight, то с левого.

Слайд 10

Цвета фона и шрифта
Свойства Background и Foreground задают соответственно цвет фона и

Цвета фона и шрифта Свойства Background и Foreground задают соответственно цвет фона
текста элемента управления.
Простейший способ задания цвета в коде xaml: Background="#ffffff". В качестве значения свойство Background (Foreground) может принимать запись в виде шестнадцатеричного значения в формате #rrggbb, где rr - красная составляющая, gg - зеленая составляющая, а bb - синяя. Также можно задать цвет в формате #aarrggbb.
Либо можно использовать названия цветов напрямую:
Однако при компиляции будет создаваться объект SolidColorBrush, который и будет задавать цвет элемента. То есть определение кнопки выше фактически будет равноценно следующему:

Слайд 11

SolidColorBrush представляет собой кисть, покрывающую элемент одним цветом. Позже мы подробнее поговорим

SolidColorBrush представляет собой кисть, покрывающую элемент одним цветом. Позже мы подробнее поговорим
о цветах. А пока надо знать, что эти записи эквивалентны, кроме того, вторая форма определения цвета позволяет задать другие кисти - например, градиент.
Это надо также учитывать при установке или получении цвета элемента в коде c#:
Класс Colors предлагает ряд встроенный цветовых констант, которыми мы можем воспользоваться. А если мы захотим конкретизировать настройки цвета с помощью значений RGB, то можно использовать метод Color.FromRgb.

Слайд 12

Элементы управления содержимым

Элементы управления содержимым (content controls) представляют такие элементы управления, которые

Элементы управления содержимым Элементы управления содержимым (content controls) представляют такие элементы управления,
содержат в себе другой элемент. Все элементы управления содержимым наследуются от класса ContentControl, который в свою очередь наследуется от класса System.Window.Controls.Control.
К элементам управления содержимым относятся такие элементы как Button, Label, ToggleButton, ToolTip, RadioButton, CheckBox, GroupBox, TabItem, Expander, ScrollViewer. Также элементом управления содержимым является и главный элемент окна - Window.
Отличительной чертой всех этих элементов является наличие свойства Content, которое и устанавливает вложенный элемент. В этом элементы управления содержимым схожи с контейнерами компоновки. Только контейнеры могут иметь множество вложенных элементов, а элементы управления содержимым только один.
Свойство Content может представлять любой объект, который может относиться к одному из двух типов:
Объект класса, не наследующего от UIElement. Для такого объекта вызывается метод ToString(), который возвращает строковое преставление объекта. Затем эта строка устанавливается в качестве содержимого.
Объект класса, наследующего от UIElement. Для такого объекта вызывается метод UIElement.OnRender(), который выполняет отрисовку внутри элемента управления содержимым.

Слайд 13

Рассмотрим на примере кнопки, которая является элементом управления содержимым:
В качестве содержимого устанавливается

Рассмотрим на примере кнопки, которая является элементом управления содержимым: В качестве содержимого
обычная строка. Этот же пример мы можем в XAML прописать иначе:
Либо мы можем использовать сокращенное неявное определения свойства Content:

Слайд 14

Возьмем другой пример. Определим кнопку с именем button1:
А в файле коде MainWindow.xaml.cs

Возьмем другой пример. Определим кнопку с именем button1: А в файле коде
присвоим ее свойству Content какой-либо объект:
В итоге мы получим следующую кнопку:
В итоге число конвертируется в строку и устанавливается в качестве содержимого.

Слайд 15

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

Иначе все будет работать, если мы в качестве содержимого используем объект, унаследованный
от UIElement:
Теперь в качестве содержимого будет использоваться другая кнопка, для которой при визуализации будет вызываться метод OnRender():
Для создания той же кнопки через код C# мы бы могли прописать следующее выражение:

Слайд 16

В отличие от контейнеров компоновки для элементов управления содержимым мы можем задать

В отличие от контейнеров компоновки для элементов управления содержимым мы можем задать
только один вложенный элемент. Если же нам надо вложить в элемент управления содержимым несколько элементов, то мы можем использовать те же контейнеры компоновки:
То же самое мы могли бы прописать через код C#:

Слайд 17

Позиционирование контента. Content Alignment
Выравнивание содержимого внутри элемента задается свойствами HorizontalContentAlignment (выравнивание по

Позиционирование контента. Content Alignment Выравнивание содержимого внутри элемента задается свойствами HorizontalContentAlignment (выравнивание
горизонтали) и VerticalContentAlignment (выравнивание по вертикали), аналогичны свойствам VerticalAlignment/HorizontalAlignment. Свойство HorizontalContentAlignment принимает значения Left, Right, Center (положение по центру), Stretch (растяжение по всей ширине). Например:
VerticalContentAlignment принимает значения Top (положение в верху), Bottom (положение внизу), Center (положение по центру), Stretch (растяжение по всей высоте)

Слайд 18

Padding
С помощью свойства Padding мы можем установить отступ содержимого элемента:
Свойство Padding задается

Padding С помощью свойства Padding мы можем установить отступ содержимого элемента: Свойство
в формате Padding="отступ_слева отступ_сверху отступ_справа отступ_снизу".
Если со всех четырех сторон предполагается один и тот же отступ, то, как и в случае с Margin, мы можем задать одно число:
Важно понимать, от какой точки задается отступ. В случае с первой кнопкой в ней контект выравнивается по левому краю, поэтому отступ слева будет предполагать отступ от левого края элемента Button. А вторая кнопка располагается по центру. Поэтому для нее отступ слева предполагает отступ от той точки, в которой содержимое бы находилось при центрировании без применения Padding.
Комбинация значений свойств HorizontalContentAlignment/VerticalContentAlignment и Padding позволяет оптимальным образом задать расположение содержимого.

Слайд 19

Кнопки
В WPF кнопки представлены целым рядом классов, которые наследуются от базового класса

Кнопки В WPF кнопки представлены целым рядом классов, которые наследуются от базового класса ButtonBase:
ButtonBase:

Слайд 20

Button
Элемент Button представляет обычную кнопку:
От класса ButtonBase кнопка наследует ряд событий, например,

Button Элемент Button представляет обычную кнопку: От класса ButtonBase кнопка наследует ряд
Click, которые позволяют обрабатывать пользовательский ввод.
Чтобы связать кнопку с обработчиком события нажатия, нам надо определить в самой кнопке атрибут Click. А значением этого атрибута будет название обработчика в коде C#. А затем в самом коде C# определить этот обработчик.
Например, код xaml:
И обработчик в коде C#:
Либо можно не задавать обработчик через атрибут, а стандартным образом для C# прописать в коде: button1.Click+=Button_Click;

Слайд 21

Кнопка имеет такие свойства как IsDefault и IsCancel, которые принимают значения true и false.
Если свойство

Кнопка имеет такие свойства как IsDefault и IsCancel, которые принимают значения true
IsDefault установлено в true, то при нажатии клавиши Enter будет вызываться обработчик нажатия этой кнопки.
Аналогично если свойство IsCancel будет установлено в true, то при нажатии на клавишу Esc будет вызываться обработчик нажатия этой кнопки.
Например, определим код:

Слайд 22


Теперь при нажатии на клавишу Enter будет отображаться сообщение, а при нажатии

Теперь при нажатии на клавишу Enter будет отображаться сообщение, а при нажатии
на Esc будет происходить выход из приложения и закрытие окна.

Слайд 23

RepeatButton
Отличительная особенность элемента RepeatButton - непрерывная генерация события Click, пока нажата кнопка.

RepeatButton Отличительная особенность элемента RepeatButton - непрерывная генерация события Click, пока нажата
Интервал генерации события корректируется свойствами Delay и Interval.
Сам по себе элемент RepeatButton редко используется, однако он может служить основой для создания ползунка в элементах ScrollBar и ScrollViewer, в которых нажатие на ползунок инициирует постоянную прокрутку.
ToggleButton
Представляет элементарный переключатель. Может находиться в трех состояниях - true, false и "нулевом" (неотмеченном) состоянии, а его значение представляет значение типа bool в языке C#. Состояние можно установить или получить с помощью свойства IsChecked. Также добавляет три события - Checked (переход в отмеченное состояние), Unchecked (снятие отметки) и Intermediate (если значение равно null). Чтобы отрабатывать все три события, надо установить свойство IsThreeState="True"
ToggleButton, как правило, сам по себе тоже редко используется, однако при этом он служит основой для создания других более функциональных элементов, таких как checkbox и radiobutton.

Слайд 24

CheckBox
Элемент CheckBox представляет собой обычный флажок. Данный элемент является производным от класса

CheckBox Элемент CheckBox представляет собой обычный флажок. Данный элемент является производным от
ToggleButton и поэтому может принимать также три состояния: Checked, Unchecked и Intermediate.
Чтобы получить или установить определенное состояние, надо использовать свойство IsChecked, которое также унаследовано от ToggleButton:
Установка свойства IsChecked="{x:Null}" задает неопределенное состояние для элемента checkbox. Остальные два состояния задаются с помощью True и False. В данном примере также привязан к двум флажкам обработчик события Checked. Это событие возникает при установке checkbox в отмеченное состояние.
А атрибут IsThreeState="True" указывает, что флажок может находиться в трех состояниях.

Слайд 25

Ключевыми событиями флажка являются события Checked (генерируется при установке флажка в отмеченное состояние), Unchecked (генерируется при

Ключевыми событиями флажка являются события Checked (генерируется при установке флажка в отмеченное
снятии отметки с флажка) и Indeterminate (флажок переведен в неопределенное состояние). Например, определим флажок:
А в файле кода C# пропишем для него обработчики:

Слайд 26

Программное добавление флажка:

Программное добавление флажка:

Слайд 27

RadioButton
Элемент управления, также производный от ToggleButton, представляющий переключатель. Главная его особенность -

RadioButton Элемент управления, также производный от ToggleButton, представляющий переключатель. Главная его особенность
поддержка групп. Несколько элементов RadioButton можно объединить в группы, и в один момент времени мы можем выбрать из этой группы только один переключатель. Например,

Слайд 28

Чтобы включить элемент в определенную группу, используется свойство GroupName. В данном случае

Чтобы включить элемент в определенную группу, используется свойство GroupName. В данном случае
у нас две группы - Languages и Technologies. Мы можем отметить не более одного элемента RadioButton в пределах одной группы, зафиксировав тем самым выбор из нескольких возможностей.
Чтобы проследить за выбором того или иного элемента, мы также можем определить у элементов событие Checked и его обрабатывать в коде:
Обработчик в файле кода:

Слайд 29

Программное добавление элемента RadioButton:

Программное добавление элемента RadioButton:

Слайд 30

Всплывающие подсказки ToolTip и Popup
Элемент ToolTip представляет всплывающую подсказку при наведении на

Всплывающие подсказки ToolTip и Popup Элемент ToolTip представляет всплывающую подсказку при наведении
какой-нибудь элемент. Для определения всплывающей подсказки у элементов уже есть свойство ToolTip, которому можно задать текст, отображаемый при наведении:
Также мы можем более точно настроить всплывающую подсказку с помощью свойства Button.ToolTip:
Всплывающие подсказки можно применять не только кнопкам, но и ко всем другим элементам управления, например, к текстовому блоку:

Слайд 31

Оба определения всплывающей подсказки будут аналогичны.
Поскольку ToolTip является элементом управления содержимого, то

Оба определения всплывающей подсказки будут аналогичны. Поскольку ToolTip является элементом управления содержимого,
в него можно встроить другие элементы для создания более богатой функциональности. Например:
Здесь у нас два переключателя, и на одном из них определен расширенный элемент ToolTip: а именно в него вложен элемент Image, выводящий изображение, и элемент TextBlock. Таким образом, можно создавать всплывающие подсказки с различным наполнением.
Изображение для элемента Image в данном случае было добавлено в проект.

Слайд 32

Свойства ToolTip
Некоторые полезные свойства элемента Tooltip:
HasDropShadow: определяет, будет ли всплывающая подсказка отбрасывать

Свойства ToolTip Некоторые полезные свойства элемента Tooltip: HasDropShadow: определяет, будет ли всплывающая
тень.
Placement: определяет, как будет позиционироваться всплывающая подсказка на окне приложения. По умолчанию ее верхний левый угол позиционируется на указатель мыши.
HorizontalOffset/VerticalOffset: определяет смещение относительно начального местоположения.
PlacementTarget: определяет позицию всплывающей подсказки относительно другого элемента управления.

Слайд 33

Применим свойства:

Применим свойства:

Слайд 34

Здесь у нас три переключателя. У первого мы задаем свойства через элемент

Здесь у нас три переключателя. У первого мы задаем свойства через элемент
ToolTip. Для второго переключателя мы также можем задать свойства, несмотря на то, что здесь мы всплывающую подсказку задаем просто ToolTip="Цена: 29990 рублей" Content="Nexus 5X". В этом случае мы можем использовать прикрепленные свойства класса ToolTipService:
InitialShowDelay: задает задержку перед отображением всплывающей подсказки
ShowDuration: устанавливает время отображения всплывающей подсказки
BetweenShowDelay: устанавливает время, в течение которого пользователь сможет перейти к другому элементу с подсказкой, и для этого элемента не будет работать свойство InitialShowDelay (если оно указано)
ToolTip: устанавливает содержимое всплывающей подсказки
HasDropShadow: определяет, будет ли подсказка отбрасывать тень
ShowOnDisabled: устанавливает поведение всплывающей подсказки для недоступного элемента (со значением IsEnabled="True"). Если это свойство равно true, то подсказка отображается для недоступных элементов. По умолчанию равно false.
Placement / HorizontalOffset / VerticalOffset / PlacementTarget: те же свойства, что и у элемента ToolTip, которые устанавливают положение всплывающей подсказки

Слайд 35

Программное создание всплывающей подсказки
Допустим, в коде XAML у нас определена следующая кнопка:
Тогда

Программное создание всплывающей подсказки Допустим, в коде XAML у нас определена следующая
в файле кода C# мы могли бы определить всплывающую подсказку для кнопки так:

Слайд 36

Popup
Элемент Popup также представляет всплывающее окно, только в данном случае оно имеет

Popup Элемент Popup также представляет всплывающее окно, только в данном случае оно
другую функциональность. Если Tooltip отображается автоматически при наведении и также автоматически скрывается через некоторое время, то в случае с Popup все эти действия нам надо задавать вручную.
Так, чтобы отразить при наведении мыши на элемент всплывающее окно, нам надо соответственным образом обработать событие MouseEnter.
Второй момент, который надо учесть, это установка свойства StaysOpen="False". По умолчанию оно равно True, а это значит, что при отображении окна, оно больше не исчезнет, пока мы не установим явно значение этого свойства в False.
Итак, создадим всплывающее окно:

Слайд 37

И обработчик наведения курсора мыши на кнопку в коде c#:
И при наведении

И обработчик наведения курсора мыши на кнопку в коде c#: И при
указателя мыши на элемент появится всплывающее окно с сообщением.

Слайд 38

Контейнеры GroupBox и Expander
Особая группа элементов управления образована от класса HeaderedContentControl, который

Контейнеры GroupBox и Expander Особая группа элементов управления образована от класса HeaderedContentControl,
является подклассом ContentControl. Эта группа отличается тем, что позволяет задать заголовок содержимому. В эту группу элементов входят GroupBox и Expander.
GroupBox
Элемент GroupBox организует наборы элементов управления в отдельные группы. При этом мы можем определить у группы заголовок:
GroupBox включает группу различных элементов, однако, как и всякий элемент управления содержимым, он принимает внутри себя только один контейнер, поэтому сначала мы вкладываем в GroupBox общий контейнер, а в него уже все остальные элементы.

Слайд 39

Однако заголовок GroupBox необязательно представляет простой текст. Мы можем пойти дальше и

Однако заголовок GroupBox необязательно представляет простой текст. Мы можем пойти дальше и
изменить предыдущий пример, засунув кнопку заказа прямо в заголовок:
Осталось добавить обработчик нажатия кнопки Click для обработки заказа и можно заказывать блюда.

Слайд 40

Expander
Представляет скрытое содержимое, раскрывающееся по нажатию мышкой на указатель в виде стрелки.

Expander Представляет скрытое содержимое, раскрывающееся по нажатию мышкой на указатель в виде
Причем содержимое опять же может быть самым разным: кнопки, текст, картинки и т.д.
С помощью свойства IsExpanded можно задать раскрытие узла при старте приложения. По умолчанию узел скрыт. Пример использования:

Слайд 41

Опять же мы можем изменить заголовок, вложив в него, например, кнопку или

Опять же мы можем изменить заголовок, вложив в него, например, кнопку или
изображение:
Если мы хотим обработать открытие экспандера, то нам надо обработать событие Expanded (а при обработке закрытия - событие Collapsed). Данные события вызываются до самого действия, поэтому мы можем перед открытием, например, динамически устанавливать содержание экспандера:
А обработка событий в файле C# могла бы выглядеть так:
В итоге при раскрытии элемента вместо начального содержимого там будет определенная в коде кнопка.

Слайд 42

ScrollViewer. Создание прокрутки
Элемент ScrollViewer обеспечивает прокрутку содержимого. Может вмещать в себя только

ScrollViewer. Создание прокрутки Элемент ScrollViewer обеспечивает прокрутку содержимого. Может вмещать в себя
один элемент, поэтому все элементы, помещаемые внутрь ScrollViewer необходимо облачить в еще один контейнер. Например:

Слайд 43

ScrollViewer поддерживает как вертикальную, так и горизонтальную прокрутку. Ее можно установить с

ScrollViewer поддерживает как вертикальную, так и горизонтальную прокрутку. Ее можно установить с
помощью свойств HorizontalScrollBarVisibility и VerticalScrollBarVisibility. Эти свойства принимают одно из следующих значений:
Auto: наличие полос прокрутки устанавливается автоматически
Visible: полосы прокрутки отображаются в окне приложения
Hidden: полосы прокрутки не видно, но прокрутка возможна с помощью клавиш клавиатуры
Disabled: полосы прокрутки не используются, а сама прокрутка даже с помощью клавиатуры невозможна
Среди свойств нужно отметить еще CanContentScroll. Если оно установлено в True, то прокрутка осуществляется не на несколько пикселей, а к началу следующего элемента.
Кроме того, прокрутку можно организовать программным способом - с помощью следующих методов элемента ScrollViewer:
LineUp(), LineDown(), LineRight(), LineLeft(): прокрутка соответственно вверх, вниз, вправо, влево.
ScrollToEnd(), ScrollToHome(): прокрутка в конец окна и в начало.
ScrollToRightEnd(), ScrollToLeftEnd(): прокрутка в правый и левый конец окна.

Слайд 44

В качестве примера обернем несколько элементов RadioButton в элемент ScrollViewer:

В качестве примера обернем несколько элементов RadioButton в элемент ScrollViewer:

Слайд 45

А в файле кода C# пропишем обработчики кнопок, которые будут выполнять програмно

А в файле кода C# пропишем обработчики кнопок, которые будут выполнять програмно прокрутку:
прокрутку:

Слайд 46

Текстовые элементы управления
TextBlock
Элемент предназначен для вывода текстовой информации, для создания простых надписей:
Ключевым

Текстовые элементы управления TextBlock Элемент предназначен для вывода текстовой информации, для создания
свойством здесь является свойство Text, которое задает текстовое содержимое. Причем в случае Текст1 данное свойство задается неявно.
С помощью таких свойств, как FontFamily, TextDecorations и др., мы можем настроить отображение текста. Однако мы можем задать и более сложное форматирование, например:
Элементы Run представляют куски обычного текста, для которых можно задать отдельное форматирование.

Слайд 47

Для изменения параметров отображаемого текста данный элемент имеет такие свойства, как LineHeight,

Для изменения параметров отображаемого текста данный элемент имеет такие свойства, как LineHeight,
TextWrapping и TextAlignment.
Свойство LineHeight позволяет указывать высоту строк.
Свойство TextWrapping позволяет переносить текст при установке этого свойства TextWrapping="Wrap". По умолчанию это свойство имеет значение NoWrap, поэтому текст не переносится.
Свойство TextAlignment выравнивает текст по центру (значение Center), правому (Right) или левому краю (Left):
Для декорации текста используется свойство TextDecorations, например, если TextDecorations="Underline", то текст будет подчеркнут.
Если нам вдруг потребуется перенести текст на другую строку, то тогда мы можем использовать элемент LineBreak:

Слайд 48

TextBox
Если TextBlock просто выводит статический текст, то этот элемент представляет поле для

TextBox Если TextBlock просто выводит статический текст, то этот элемент представляет поле
ввода текстовой информации.
Он также, как и TextBlock, имеет свойства TextWrapping, TextAlignment и TextDecorations.
С помощью свойства MaxLength можно задать предельное количество вводимых символов.
В коде C# мы можем обработать событие изменения текста:

Слайд 49

По умолчанию, если вводимый текст превышает установленные границы поля, то текстовое поле

По умолчанию, если вводимый текст превышает установленные границы поля, то текстовое поле
растет, чтобы вместить весь текст. Но визуально это не очень хорошо выглядит. Поэтому, как и в случае с TextBlock, мы можем перенести непомещающийся текст на новую строку, установив свойство TextWrapping="Wrap".
Чобы переводить по нажатию на клавишу Enter курсор на следующую строку, нам надо установить свойство AcceptsReturn="True".
Также мы можем добавить полю возможность создавать табуляцию с помощью клавиши Tab, установив свойство AcceptsTab="True".
Для отображения полос прокрутки TextBox поддерживает свойства VerticalScrollBarVisibility и НоrizontalScrollBarVisibility:

Слайд 50

Возможно, при создании приложения нам потребуется сделать текстовое поле недоступным для ввода

Возможно, при создании приложения нам потребуется сделать текстовое поле недоступным для ввода
(на время в зависимости от условий или вообще), тогда для этого нам надо установить свойство IsReadOnly="True".
Для выделения текста есть свойства SelectionStart, SelectionLength и SelectionText. Например, выделим программно текст по нажатию кнопки:
Обработчик нажатия кнопки:

Слайд 51

Проверка орфографии
TextBox обладает встроенной поддержкой орфографии. Чтобы ее задействовать, надо установить свойство

Проверка орфографии TextBox обладает встроенной поддержкой орфографии. Чтобы ее задействовать, надо установить
SpellCheck.IsEnabled="True". Кроме того, по умолчанию проверка орфографии распространяется только на английский язык, поэтому, если приложение заточено под другой язык, нам надо его явным образом указать через свойство Language:

Слайд 52

Метка (Label)
Главной особенностью меток является поддержка мнемонических команд-клавиш быстрого доступа, которые передают

Метка (Label) Главной особенностью меток является поддержка мнемонических команд-клавиш быстрого доступа, которые
фокус связанному элементу. Например,
Теперь, нажав на клавишу "п", мы переведем фокус на связанное текстовое поле. При вызове приложения подчеркивание не отображается, чтобы отображать подчеркивание, надо нажать на клавишу Alt. Тогда чтобы перевести фокус на связанное текстовое поле необходимо будет нажать сочетание Alt + "п". Если не предполагается использование клавиш быстрого доступа, то для вывода обычной текста вместо меток лучше использовать элемент TextBlock.
PasswordBox
Элемент предназначен для ввода парольной информации. По сути это тоже текстовое поле, только для ввода символов используется маска. Свойство PasswordChar устанавливает символ маски, отображаемый при вводе пароля. Если это свойство не задано, то по умолчанию для маски символа используется черная точка. Свойство Password устанавливает парольную строку, отображаемую по умолчанию при загрузке окна приложения.

Слайд 53

Элементы управления списками
Эти элементы представлены в WPF довольно широко. Все они являются

Элементы управления списками Эти элементы представлены в WPF довольно широко. Все они
производными от класса ItemsControl, который в свою очередь является наследником класса Control. Все они содержат коллекцию элементов. Элементы могут быть напрямую добавлены в коллекцию, возможна также привязка некоторого массива данных к коллекции.
Возьмем простейший элемент-список - ListBox:

Слайд 54

Все элементы, размещенные внутри спискового элемента ListBox, представляют элементы списка.
Коллекция объектов внутри

Все элементы, размещенные внутри спискового элемента ListBox, представляют элементы списка. Коллекция объектов
элемента-списка доступна в виде свойства Items. Для управления элементами из этой коллекции мы можем использовать следующие методы:
Add(object item): добавление элемента
Clear(): полная очистка коллекции
Insert(int index, object item): вставка элемента по определенному индексу в коллекции
Remove(object item): удаление элемента
RemoveAt(int index): удаление элемента по индексу
А свойство Count позволяет узнать, сколько элементов в коллекции.
Например, применительно к вышеопределенному списку мы бы могли написать в коде C#:

Слайд 55

Нам необязательно вручную заполнять значения элемента управления списком, так как мы можем

Нам необязательно вручную заполнять значения элемента управления списком, так как мы можем
установить свойство ItemsSource, задав в качестве параметра коллекцию, из которой будет формироваться элемент управления списком. Например, в коде xaml-разметки определим пустой список:
А в файле отделенного кода выполним наполнение списка:
Свойство ItemsSource в качестве значения принимает массив, хотя это моет быть и список типа List. И каждый элемент этого массива переходит в ListBox.

Слайд 56

Еще одно важное свойство списковых элементов - это свойство DisplayMemberPath. Оно позволяет выбирать

Еще одно важное свойство списковых элементов - это свойство DisplayMemberPath. Оно позволяет
для отображения элементов значение одного из свойств объекта. Например, создадим в коде новый класс Phone:
Теперь создадим в xaml набор объектов этого класса Phone и выведем в списке значение свойства Title этих объектов:

Слайд 57

Поскольку мы используем класс, определенный в текущем проекте, то соответственно у нас

Поскольку мы используем класс, определенный в текущем проекте, то соответственно у нас
обязательно должно быть подключено пространство имен проекте: xmlns:local="clr-namespace:ControlsApp". В принципе по умолчанию WPF уже его подключает. Кроме того, чтобы не возникало проблем с разметкой XAML, желательно сделать перестроение проекта. И в итоге окно нам выведет названия смартфонов:

Слайд 58

То же самое мы бы могли сделать программным способом:
Все элементы управления списками

То же самое мы бы могли сделать программным способом: Все элементы управления
поддерживают выделение входящих элементов. Выделенный элемент(ы) можно получить с помощью свойств SelectedItem(SelectedItems), а получить индекс выделенного элемента - с помощью свойства SelectedIndex. Свойство SelectedValue позволяет получить значение выделенного элемента.
При выделении элемента в списке генерируется событие SelectionChanged, которое мы можем обработать. Например, возьмем предыдущий список:
А в файле кода определим обработчик для этого события:
Важно учитывать, что так как в разметке xaml в списке определены элементы Phone, то в коде мы можем привести объект list.SelectedItem к типу Phone.

Слайд 59

ListBox
Представляет собой обычный список. Содержит коллекцию элементов ListBoxItem, которые являются типичными элементами

ListBox Представляет собой обычный список. Содержит коллекцию элементов ListBoxItem, которые являются типичными
управления содержимым. Также ListBox может содержать любые другие элементы, например:
Все эти элементы будут находиться в коллекции phonesList.Items и, таким образом, по счетчику можно к ним обращаться, например, phonesList.Items[0] - первый элемент ListBox, который в данном случае представляет TextBlock. Также мы можем установить элемент: phonesList.Items[2]="LG G 4";

Слайд 60

Компонент ListBoxItem представляет элемент управления содержимым, поэтому также мы можем задавать через

Компонент ListBoxItem представляет элемент управления содержимым, поэтому также мы можем задавать через
его свойство Content более сложные композиции элементов, например:
Мы можем использовать элементы как внутри элемента ListBoxItem, так и непосредственно вставляя их в список. Однако на следующем примере видно, что использование ListBoxItem имеет небольшое преимущество, так как мы можем задать некоторые дополнительные свойства, например, отступы.
Выделение элементов
ListBox поддерживает множественный выбор. Для этого нужно установить свойство SelectionMode="Multiple" или SelectionMode="Extended". В последнем случае, чтобы выделить несколько элементов, необходимо держать нажатой клавишу Ctrl или Shift. По умолчанию SelectionMode="Single", то есть допускается только единственное выделение.

Слайд 61

ComboBox
ComboBox содержит коллекцию элементов и образует выпадающий список:

ComboBox ComboBox содержит коллекцию элементов и образует выпадающий список:

Слайд 62

ComboBoxItem
В качестве элементов в ComboBoxe мы можем использовать различные компоненты, но наиболее

ComboBoxItem В качестве элементов в ComboBoxe мы можем использовать различные компоненты, но
эффективным является применение элемента ComboBoxItem. ComboBoxItem представляет элемент управления содержимым, в который через свойство Content мы можем поместить другие элементы. Например:
Для создания первого элемента использовался элемент ComboBoxItem. Для второго и третьего такие элементы создаются неявно. Однако использование ComboBoxItem имеет преимущество, так как мы можем выделить данный элемент, установив свойство IsSelected="True", либо можем сделать недоступным с помощью установки свойства IsEnabled="False".

Слайд 63

Событие SelectionChanged
Обрабатывая событие SelectionChanged, мы можем динамически получать выделенный элемент:
Обработка события в

Событие SelectionChanged Обрабатывая событие SelectionChanged, мы можем динамически получать выделенный элемент: Обработка
коде C#:
Правда, для элементов со сложным содержимым подобный способ может не пройти, и если мы захотим получить текст, до него придется добираться, спускаясь по дереву вложенных элементов.
Свойства
Установка свойства IsEditable="True" позволяет вводить в поле списка начальные символы, а затем функция автозаполнения подставит подходящий результат. По умолчанию свойство имеет значение False.
Это свойство работает в комбинации со свойством IsReadOnly: оно указывает, является поле ввода доступным только для чтения. По умолчанию имеет значение False, поэтому если IsEditable="True", то мы можем вводить туда произвольный текст.
Еще одно свойство StaysOpenOnEdit при установке в True позволяет сделать список раскрытым на время ввода значений в поле ввода.

Слайд 64

ListView
Этот элемент управления отображает информацию на множестве строк и столбцов. Он унаследован

ListView Этот элемент управления отображает информацию на множестве строк и столбцов. Он
от класса ListBox, поэтому может вести себя простой список:
Но чтобы создать более сложные по структуре данные используется свойство View. Это свойство принимает в качестве значения объект GridView, который управляет отображением данных. GridView определяет коллекцию определений столбцов - GridViewColumn, которое с помощью свойства Header определяет название столбца, а с помощью свойства DisplayMemberBinding можно определить привязку столбца к определенному свойству добавляемого в ListView объекта.

Слайд 65

Допустим у нас в проекте определен класс Phone:
Создадим в xaml-коде коллекцию объектов

Допустим у нас в проекте определен класс Phone: Создадим в xaml-коде коллекцию
Phone (в принципе это можно было бы сделать и в файле кода) и объявим привязку столбцов ListView к свойствам объектов Phone:

Слайд 67

Создание вкладок и TabControl
Для создания вкладок в WPF, как и в WinForms,

Создание вкладок и TabControl Для создания вкладок в WPF, как и в
предназначен элемент TabControl, а отдельная вкладка представлена элементом TabItem:
Элемент TabItem является элементом управления содержимым, поэтому в него можно вложить другие элементы:

Слайд 68

Класс TabItem наследуется от класса HeaderedContentControl, поэтому кроме свойства Content, определедяющее содержимое

Класс TabItem наследуется от класса HeaderedContentControl, поэтому кроме свойства Content, определедяющее содержимое
вкладки, имеет также свойство Header, которое определяет заголовок. И в этот заголовок мы можем вложить различное содержимое, как в примере выше.
И также, как и в случае с ListBoxItem и ComboBoxItem, мы можем вложить в TabControl и другие элементы, которые неявно образуют отдельные вкладки:
Программное добавление вкладок
Допустим, у нас на форме есть TabControl:
Через код C# добавим в него вкладку:

Слайд 69

Меню
Menu
Данный элемент служит для создания стандартных меню:
Элемент Menu включает набор элементов MenuItem,

Меню Menu Данный элемент служит для создания стандартных меню: Элемент Menu включает
которые опять же являются элементами управления содержимым и могут включать другие элементы MenuItem и не только. Также мы можем вложить в меню и другие элементы, которые неявно будут преобразованы в MenuItem. Например:

Слайд 70

Также для разделения отдельных пунктов меню можно включать элемент Separator, как в

Также для разделения отдельных пунктов меню можно включать элемент Separator, как в
примере выше.
Мы также можем настроить внешний вид отображения, задав свойство MenuItem.Header или использовав свойство Icons:

Слайд 71

Чтобы обработать нажатие пункта меню и произвести определенное действие, можно использовать событие

Чтобы обработать нажатие пункта меню и произвести определенное действие, можно использовать событие
Click, однако в будущем мы познакомимся с еще одним инструментом под названием команды, который также широко применяется для реакции на нажатие кнопок меню. А пока свяжем обработчик c событием:
И определим сам обработчик в коде C#:

Слайд 72

ContextMenu
Класс ContextMenu служит для создания контекстных всплывающих меню, отображающихся после нажатия на

ContextMenu Класс ContextMenu служит для создания контекстных всплывающих меню, отображающихся после нажатия
правую кнопку мыши. Этот элемент также содержит коллекцию элементов MenuItem. Однако сам по себе ContextMenu существовать не может и должен быть прикреплен к другому элементу управления. Для этого у элементов есть свойство ContextMenu:
И при нажатии правой кнопкой мыши на один из элементов отобразится контекстное меню.

Слайд 73

ToolBar
Этот элемент, как правило, применяется для обеспечения быстрого доступа к наиболее часто

ToolBar Этот элемент, как правило, применяется для обеспечения быстрого доступа к наиболее
используемым операциям. Он может содержать прочие элементы как кнопки, текстовые поля, объекты Menu и др.

Слайд 74

Также можно создавать сразу несколько связанных элементов ToolBar внутри ToolBarTray. Преимущество его использования заключается в

Также можно создавать сразу несколько связанных элементов ToolBar внутри ToolBarTray. Преимущество его
возможности задать как горизонтальное, так и вертикальное расположение элементов ToolBar в окне приложения.

Слайд 75

Используя свойство Orientation мы можем настроить у ToolBarTray ориентацию. По умолчанию она

Используя свойство Orientation мы можем настроить у ToolBarTray ориентацию. По умолчанию она
горизонтальная, но мы можем расположить его вертикально:
Еще один элемент - StatusBar, во многом напоминает ToolBar и выполняет схожие функции, только в отличие о ToolBar его располагают обычно внизу окна приложения.

Слайд 76

TreeView
Данный элемент управления предназначен для древовидного отображения данных в окне приложения. Может

TreeView Данный элемент управления предназначен для древовидного отображения данных в окне приложения.
содержать как коллекцию элементов TreeViewItem, так и другое содержимое, например, текстовые блоки:

Слайд 77

Однако все же лучше обертывать элементы в объекты TreeViewItem. С помощью его

Однако все же лучше обертывать элементы в объекты TreeViewItem. С помощью его
свойства Header мы можем установить текстовую метку или заголовок узла дерева. Элемент TreeViewItem предлагает также ряд свойств для управления состоянием: IsExpanded (принимает логическое значение и показывает, раскрыт ли узел) и IsSelected (показывает, выбран ли узел).
Чтобы отследить выбор или раскрытие узла, мы можем обработать соответствующие события. Событие Expanded возникает при раскрытии узла, а событие Collapsed, наоборот, при его сворачивании.
Выбор узла дерева мы можем обработать с помощью обработки события Selected. Например:
Теперь добавим в файл связанного кода C# обработчики для этих событий:

Слайд 78

DataGrid
DataGrid во многом похож на ListView, но более сложный по характеру и

DataGrid DataGrid во многом похож на ListView, но более сложный по характеру
допускает редактирование содержимого таблицы.
В разделе о ListView мы создали класс Phone, объекты которого выводили в список:
Теперь же выведем объекты в таблицу DataGrid. Чтобы DataGrid автоматически разбивал таблицу на столбцы, установим свойство AutoGenerateColumns="True":

Слайд 79

В данном случае префикс local ссылается на пространство имен текущего проекта, в

В данном случае префикс local ссылается на пространство имен текущего проекта, в
котором определен класс Phone (xmlns:local="clr-namespace:Controls"), а col - префикс-ссылка на пространство имен System.Collections (xmlns:col="clr-namespace:System.Collections;assembly=mscorlib"). И это даст в итоге следующий вывод:
Программная установка источника для DataGrid:

Слайд 80

Некоторые полезные свойства DataGrid
Хотя предыдущий пример довольно прост, в нем есть несколько

Некоторые полезные свойства DataGrid Хотя предыдущий пример довольно прост, в нем есть
недочетов. Во-первых, у нас нет возможности повлиять на расстановку столбцов. Во-вторых, заголовки определены по названиям свойств, которые на английском языке, а хотелось бы на русском. В этом случае мы должны определить свойства отображения столбцов сами. Для этого надо воспользоваться свойством DataGrid.Columns и определить коллекцию столбцов для отображения в таблице.

Слайд 81

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

Причем можно задать также и другой тип столбца, отличный от текстового. DataGrid поддерживает следующие варианты столбцов:
поддерживает следующие варианты столбцов:

Слайд 82

Перепишем предыдущий пример с учетом новой информации:

Перепишем предыдущий пример с учетом новой информации:

Слайд 83

Среди свойств DataGrid одним из самых интересных является RowDetailsTemplate. Оно позволяет задать шаблон

Среди свойств DataGrid одним из самых интересных является RowDetailsTemplate. Оно позволяет задать
отображения дополнительной информации касательно данной строки. Измени элемент DataGrid:

Слайд 84

ProgressBar и Slider
ProgressBar и Slider представляют элементы, основанные на диапазонах значений. То

ProgressBar и Slider ProgressBar и Slider представляют элементы, основанные на диапазонах значений.
есть они хранят и отображают числовые данные на определенном диапазоне.
Все они являются наследниками класса RangeBase, поэтому наследуют такие его свойства, как:
Value указывает на текущее значение элемента (представлено типом Double)
Maximum/Minimum указывает на максимальное/минимальное значение элемента

Слайд 85

Slider
Представляет собой обычный ползунок. Он добавляет следующие свойства:
Orientation: указывает ориентацию ползунка -

Slider Представляет собой обычный ползунок. Он добавляет следующие свойства: Orientation: указывает ориентацию
горизонтальную(Horizontal) или вертикальную (Vertical)
Delay: указывает время в миллисекундах, по истечении которого ползунок переместится на одну единицу после щелчка.
Interval: указывает время в миллисекундах, по истечении которого ползунок может перемещаться
TickPlacement: задает визуализацию шкалы ползунка. По умолчанию имеет значение None (отсутствие шкалы). Значение BottomRight создают шкалу в нижней части ползунка, TopLeft - в верхней, Both - по обоим сторонам.
TickFrequency: указывает частоту появления отметок на шкале ползунка.
IsSelectionRangeEnabled: задает затенение участка ползунка. Если оно установлено в True, то начальная и конечная отметка затенения задаются с помощью свойств SelectionStart и SelectionEnd.

Слайд 86

Простейший слайдер:
В файле кода мы можем прописать обработчик Slider_ValueChanged, который будет срабатывать

Простейший слайдер: В файле кода мы можем прописать обработчик Slider_ValueChanged, который будет
при возникновении события ValueChanged - изменении значения слайдера. В данном случае обработчик этого события будет изменять выделение слайдера:
ProgressBar
ProgressBar представляет индикатор, отображающий выполнение определенного процесса. Также имеет свойство Orientation, которое устанавливает вертикальное или горизонтальное расположение индикатора. Для связи с реальными процессами вся логика изменения индикатора, его свойства Value должна отрабатываться в коде.

Слайд 87

Работа с изображениями. Image и InkCanvas
Элемент Image предназначен для работы с изображениями.

Работа с изображениями. Image и InkCanvas Элемент Image предназначен для работы с
Свойство Source позволяет задать путь к изображению, например:
WPF поддерживает различны форматы изображений: .bmp, .png, .gif, .jpg и т.д.
Также элемент позволяет проводить некоторые простейшие транформации с изображениями. Например, с помощью объекта FormatConvertedBitmap и его свойства DestinationFormat можно получить новое изображение:

Слайд 88

InkCanvas
InkCanvas представляет собой полотно, на котором можно рисовать. Первоначально оно предназначалось для

InkCanvas InkCanvas представляет собой полотно, на котором можно рисовать. Первоначально оно предназначалось
стилуса, но в WPF есть поддержка также и для мыши для обычных ПК. Его очень просто использовать:
Либо мы можем вложить в InkCanvas какое-нибудь изображение и на нем уже рисовать:
Все рисование в итоге представляется в виде штрихов - элементов класса System.Windows.Ink.Stroke и хранится в коллекции Strokes, определенной в классе InkCanvas.