Опубликован: 08.07.2011 | Уровень: для всех | Доступ: платный
Лекция 2:

Основы технологии WPF

< Лекция 1 || Лекция 2: 123456 || Лекция 3 >

Компоновка

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

В WPF компоновка осуществляется с использованием различных контейнеров. Каждый контейнер обладает своей собственной логикой компоновки – некоторые укладывают элементы последовательно в строки, другие организуют их в сетку невидимых ячеек

Окно и страница в WPF может содержать только один элемент - контейнер. В контейнер можно поместить различные элементы пользовательского интерфейса и другие контейнеры. Компоновка в WPF определяется типом используемого контейнера. Контейнеры компоновки WPF– это панели, порожденные от абстрактного класса System.Windows.Controls.Panel. Для компоновки в приложениях используются следующие классы:

  • Grid и UniformGrid – размещают элементы в строки и колонки в соответствии с невидимой таблицей;
  • StackPanel – размещает элементы в горизонтальные и вертикальные стопки. Этот контейнер часто используется для организации небольших участков более крупного и сложного окна;
  • WrapPanel – размещает элементы управления в доступном пространстве, по одной строке или колонке;
  • DockPanel - размещает элементы управления относительно одного из своих внешних краев;
  • Frame – аналогичен StackPanel, но является предпочтительным способом упаковки содержимого для переходов на страницы.

Grid является наиболее мощным контейнером в WPF. Большая часть всего, что можно сделать с помощью других контейнеров компоновки, можно выполнить в Grid. Grid является идеальным инструментом для разделения окна (страницы) на более мелкие области, которыми можно будет управлять с помощью других панелей.

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

Панель StackPanel является одним из простейших контейнеров компоновки. Данная панель укладывает свои дочерние элементы в одну строку или колонку.

Контейнер UniformGrid, в отличие от Grid, требует установки только количества строк и столбцов и формирует ячейки одинакового размера, которые занимают всё доступное пространство окна (страницы) или элемента внешнего контейнера.

WrapPanel в зависимости от свойства Orientation упорядочивает элементы управления горизонтально ( Horizontal ) или вертикально ( Vertical ), заполняя текущий размер панели. При горизонтальном расположении элементы управления могут переноситься на следующую строку, а при вертикальном – на следующий столбец.

Панель DockPanel осуществляет пристыковку элементов управления к одной из своих сторон в зависимости от значения свойства Dock, которое может принимать значения Left, Right, Top или Bottom. Так если элемент управления был пристыкован к верхней части DockPanel, то он растягивается и будет занимать всю ширину панели, принимая такую высоту, какая определена параметром MaxHeight.

Frame является элементом управления содержимым, который предоставляет возможность перехода к содержимому и его отображения. Frame можно разместить внутри другого содержимого, как и другие элементы управления и элементы. Содержимое может быть любым типом объекта .NET Framework и файлов HTML. Обычно Frame используется для упаковки содержимого определяющего переходы на страницы.

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

  • HorizontalAlignment и VerticalAlignment – определяет, как дочерний элемент позиционируется внутри компоновки, когда имеется дополнительное пространство по горизонтали/вертикали;
  • Margin – добавляет пустое пространство вокруг элемента;
  • MinWidth и MaxWidth – устанавливает максимальные размерности для элемента;
  • Width и Height – явно устанавливает размеры элемента.

В WPF существуют контейнеры, которые располагают элементы управления в соответствии заданными координатами, заданными размерами. Это контейнеры Canvas и InkCanvas. Данные контейнеры в большей степени предназначены для визуализации графических примитивов и фигур.

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

Элементы управления предназначены для поддержки интерактивной связи с пользователем. Они могут принимать фокус и получать входные данные от клавиатуры или мыши.

Элементы управления содержимым являются специализированным типом элементов управления, которые могут хранить некоторое содержимое – один или несколько элементов. Все элементы управления содержимым являются наследниками класса ContentControl ( рис. 2.3).

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

увеличить изображение
Рис. 2.3. Иерархия элементов управления содержимым

Класс ContentControl наследуется от класса System.Windows.Control, который наделяет его и все дочерние классы базовыми характеристиками, которые:

  • позволяют определять содержимое внутри элемента управления;
  • позволяют определять порядок перехода с использованием клавиш табуляции;
  • поддерживают рисование фона, переднего плана и рамки;
  • поддерживают форматирование размера и шрифта текстового содержания.

Элементы управления имеют фон и передний план. Фоном, как правило, является поверхность элемента управления, а передним планом – текст. Цвет этих двух областей в WPF определяется с помощью свойств Background и Foreground. Эти свойства используют кисти – объект Brush. Это обеспечивает заливку содержимого фона и переднего плана сплошным цветом (класс кисти SolidColorBrush ) или градиентным, например с помощью класса кисти LinearGradientBrush.

Для задания фона кнопки с помощью объекта Brush необходимо свойству Color кисти SolidColorBrush присвоить значение, например Blue – голубой.

<Button>Кнопка A
   <Button.Background>
      <SolidColorBrush Color="Blue"></SolidColorBrush>
   </Button.Background>
</Button>

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

<Button Background="Black" Foreground="Red">Кнопка A</Button>

При этом синтаксический анализатор WPF автоматически создаст объекты SolidColorBrush с использованием заданных цветов, и будет применять созданные объекты для фона и переднего плана.

Если необходимо использовать другой тип кисти, например градиентный – LinearGradientBrush, то следует создавать объект кисти самостоятельно:

<Button>Кнопка A
  <Button.Background>
    <LinearGradientBrush>
    <LinearGradientBrush.GradientStops>
       <GradientStop Offset="0.0" Color="Blue"></GradientStop>
       <GradientStop Offset="1.0" Color="Red"></GradientStop>
    </LinearGradientBrush.GradientStops>
    </LinearGradientBrush>
  </Button.Background>
</Button>

С помощью кисти рисуется рамка вокруг элемента управления. Это реализуется с помощью свойств BorderBrush и BorderThickness. При этом свойство BorderBrush принимает выбранную кисть, а BorderThickness – ширину рамки:

<Button Width="80" Height="30" Background="Red" 
BorderBrush="Blue" BorderThickness="5">Кнопка A</Button>

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

  • с помощью свойства Opacity (непрозрачность), которое может принимать значение от 0 до 1. Значение 1 соответствует полностью непрозрачному цвету, а 0 – полностью прозрачному;
  • с помощью полупрозрачного цвета через задание значения альфа-канала. Значение альфа-канала менее 255, является полупрозрачным.

Класс Control, от которого наследуются все элементы управления, определяет набор свойств, связанных со шрифтами:

  • FontFamily – имя шрифта для использования в элементе контроля;
  • FontSize – размер ширфта в единицах, не зависящих от устройства (каждая из них представляет собой 1/96 дюйма);
  • FontStyle – представляет наклон текста;
  • FontWeight – вес текста;
  • FontStretch – величина на которую растягивается или сжимается текст.

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

<Button FontFamily="Times New Roman" FontSize="18">Кнопка A</Button>

При задании полужирного шрифта с наклоном необходимо задать следующие свойства:

<Button FontFamily="Times New Roman" 
FontSize="18" FontStyle="Italic" FontWeight="Bold"> Кнопка A</Button>

Многие элементы управления WPF являются элементами управления содержимым. Это элементы управления: Label, Button, CheckBox и RadioButton.

МеткаLabel является простейшим элементом управления содержимым. Она принимает одиночную порцию содержимого, которую необходимо поместить внутри неё. Метка поддерживает мнемонические команды – клавишу быстрого доступа, передавая фокус связанному с ней элементу управления. Для поддержки этой функции используют свойство Target, которому присваивают выражение привязки. В выражении привязки необходимо указать другой элемент управления, на который будет переходить фокус при нажатии клавиши быстрого доступа.

<Label Target="{Binding ElementName = txtA}">Выбор _А</Label> 
<TextBox Name="txtA">Выбор текста</TextBox>

Символ подчеркивания в тексте метки указывает на клавишу быстрого доступа. Все мнемонические команды работают при одновременном нажатии клавиши <Alt> и заданной клавиши быстрого доступа. В приведенном выше коде при нажатии комбинации <Alt+A> фокус перейдет на элемент управления TextBox с именем txtA.

В WPF определены три класса: Button, CheckBox и RadioButton, которые наследуются от класса ButtonBase.

Класс ButtonBase определяет событие Click и добавляет поддержку команд, которые позволяют подключить кнопки для высокоуровневых задач приложения. В классе ButtonBase имеется свойство ClickMode, которое определяет когда кнопка генерирует событие Click в ответ на действия мыши. Значением, используемым по умолчанию, является ClickMode.Release, которое означает, что событие будет сгенерировано как при нажатии, так и при отпускании кнопки мыши. Для ClickMode.Press – событие будет генерироваться только при нажатии кнопки мыши, ClickModeHover – когда указатель мыши будет наведен на кнопку и задержен на ней.

Класс Button добавляет два свойства, доступные для записи: IsCancel и IsDefault.

При IsCancel = true кнопка будет работать как кнопка отмены окна и если нажать кнопку <Esc>, когда текущее окно находится в фокусе, то кнопка сработает.

Если IsDefault= true, то кнопка считается кнопкой по умолчанию.

Классы CheckBox и RadioButton наследуются от класса ToggleButton, который представляет кнопку, имеющую два состояния: нажата и отпущена. В классе имеются события Checked, Unchecked и Intermediate, которые генерируются при включении, выключении или переходе кнопки в неопределенное состояние.

Для кнопки CheckBox включение элемента управления означает отметку в нем флажка. Свойство IsChecked, наследуемое от класса ToggleButton, может принимать три значения: true (включено), false (выключено), null (неопределено, которое отображается в виде затененного окна, и используется для промежуточного состояния). Пример XAML-описания трех кнопок CheckBox приведен ниже.

<CheckBox Height="16" Name="checkBox1" 
      Width="120" IsChecked="False" 
	  ClickMode="Release">Выбор А</CheckBox>
<CheckBox Height="16" Name="checkBox2" 
      Width="120" IsChecked="True" 
	  ClickMode="Press">Выбор Б</CheckBox>
<CheckBox Height="16" Name="checkBox3" 
      Width="120" IsChecked="{x:Null}" 
	  ClickMode="Hover">Выбор В</CheckBox>

Для кнопки RadioButton добавлено свойство GroupName, которое позволяет управлять расположением переключателей в группе. Из группы можно выбрать только один переключатель.

<GroupBox Header="Группа радиокнопок" Height="100"
Name="groupBox1" Width="200">
  <StackPanel>
   <RadioButton Height="16" Name="radioButton2" 
Width="120">Выбор Г</RadioButton>
   <RadioButton Height="16" Name="radioButton1" 
 Width="120">Выбор Д</RadioButton>
   <RadioButton Height="16" Name="radioButton3"  
Width="120">Выбор Е</RadioButton>
  </StackPanel>
</GroupBox>

Контекстные окна указателя ToolTip позволяют выводить всплывающие окна, когда пользователь наводит указатель мыши на определенный элемент. Данные окна в WPF относятся к группе элементов управления содержимым и поэтому в них можно помещать любое допустимое содержимое. Для вывода контекстного окна указателя не обязательно использовать класс ToolTip. Можно воспользоваться свойством ToolTip элемента управления, например для кнопки:

<Button ToolTip="Подсказка для кнопки А"></Button>

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

Элемент UserControl предназначен для создания пользовательских элементов контроля, в которых можно объединять нескольно элементов управления.

Элемент Windows является элементом управления содержимым и используется для создания всех окон приложения.

Элемент HeaderedContentControl наследуется от класса ContentControl. HeaderedContentControl является родительским классом для элементов управления, которые имеют кроме содержимого и область заголовка.

Элемент управления GroupBox является окном с заголовком и используется для группирования связанных элементов управления, например радиокнопок.

Элемент управления TabItem представляет страницу для класса TabControl. Данный элемент отображает вкладку, которая активна в данный момент на панели TabControl.

Элемент управления Expander позволяет показывать и скрывать определенную область содержимого.

< Лекция 1 || Лекция 2: 123456 || Лекция 3 >
Александр Петров
Александр Петров

При загрузке данных из БД возникает исключение InvalidOperationException с сообщением: Элемент коллекции должен быть пустым перед использованием ItemsSource. Знаю, что для заполнения DataGrid можно использовать коллекции Items или ItemsSource, но одновременно их использовать нельзя: если задано значение для свойства ItemsSource и в коде C# добавляется элемент в Items, возникает исключение. 
Вопрос, как отследить и отключить добавление элемента в Items?

Максим Спиридонов
Максим Спиридонов

В пятой лекции на второй странице в компиляторе выскакивает ошибка в строчке :

ObjectQuery<Employee> employees = DataEntitiesEmployee.Employees;

Ошибка CS0029

Не удается неявно преобразовать тип "System.Data.Entity.DbSet<WpfApplProject.Employee>" в "System.Data.Entity.Core.Objects.ObjectQuery<WpfApplProject.Employee>".

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

Igor Chelyadinski
Igor Chelyadinski
Беларусь, Минск, №54, 2013
Валентина Алешина
Валентина Алешина
Россия