Работа с Grid

97

На первой вкладке пользовательского интерфейса рассматриваемого в предыдущей статье примера проекта должны отображаться данные, введенные пользователем и зафиксированные средствами прикладного интерфейса Ink API, который поддерживается на обеих платформах, WPF и Silverlight, хотя применяемые на этих платформах модели программирования немного отличаются.

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

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

Режим компоновки на сетке

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

Режим компоновки на полотне

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

В устанавливаемом по умолчанию режиме компоновки на сетке порожденные объекты можно помещать в ячейках сетки и задавать (прямо или косвенно) поля с помощью свойства Margin объекта, содержащегося в диспетчере компоновки типа Grid. У каждого элемента пользовательского интерфейса, располагаемого на сетке, могут быть четыре поля - верхнее, нижнее, левое и правое. Эти поля определяют положение элемента в ячейке сетки и могут быть отредактированы в области Layout на панели Properties с помощью упомянутых выше свойств Margin.

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

Режим компоновки на полотне отличается тем, что порожденные объекты сетки имеют абсолютное расположение. Поэтому, если изменяются размеры любых строк и столбцов сетки, размеры порожденных объектов не изменяются автоматически, хотя их свойства Margin по-прежнему обновляются. Чаще всего для разработки пользовательского интерфейса достаточно устанавливаемого по умолчанию режима компоновки на сетке, но для перехода из одного режима компоновки в другой следует щелкнуть на кнопке-переключателе в левом верхнем углу выбранного редактора сетки:

Переключение режимов на сетке и полотне

Определение строк и столбцов Grid

Ввод строк и столбцов в выбранный объект типа Grid осуществляется в среде Expression Blend IDE довольно просто. Для этого активизируйте сначала сам объект типа Grid во вкладке Fun with Ink на панели Objects and Timeline, а затем разделите этот объект на две строки непосредственно на монтажном столе таким образом, чтобы верхняя строка занимала около четверти всего пользовательского интерфейса. С этой целью поместите курсор на внешнем крае сетки и щелкните кнопкой мыши:

Разделение Grid на две строки

Подобным способом можно ввести любое количество строк или столбцов, а после этого переставить их, перетаскивая соответствующие разделители мышью. Попробуйте ввести еще несколько строк и столбцов и поупражняйтесь в изменении размеров каждой ячейки сетки. По завершении отмените все предыдущие операции, нажимая комбинацию клавиш <Ctrl+Z> до тех пор, пока не вернетесь к виду сетки с двумя строками.

Заполнить сетку строками и столбцами можно и с помощью свойств ColumnDefinitions и RowDefinitions, находящихся среди дополнительных свойств, доступных в области Layout на панели Properties.

Ввод элементов в ячейки сетки

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

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

Ввод элемента в строку сетки

Прежде чем вводить элементы в верхней строке сетки, рассмотрим свойства выбранного объекта типа InkCanvas, доступные в области Layout на панели Properties:

Прикрепляемые свойства

В этой области можно задавать поля, высоту и ширину (в настоящий момент они установлены в режим Auto, поскольку данный объект привязан к своему родительскому объекту), а также указывать вручную строку и столбец для размещения выбранного элемента, если он, конечно, находится на сетке. Попробуйте изменить установки в этих свойствах и обратите внимание на то, каким образом изменяется расположение объекта типа InkCanvas, а затем нажмите комбинацию клавиш <Ctrl+Z>, чтобы вернуться к исходной компоновке.

Создание разделителя сетки (GridSplitter)

Многие объекты типа Grid становятся невидимыми во время выполнения, а это означает, что пользователь вообще не будет видеть строки и столбцы сетки. Но если вам действительно требуется показать линии сетки, установите логическое значение true в свойстве ShowGridLines (Показ линий сетки). Несмотря на то что пользователь вообще не видит строки и столбцы сетки в диспетчере компоновки типа Grid очень часто в сетке предоставляются видимые разделители, с помощью которых пользователь может изменять размеры строк и столбцов сетки.

Для демонстрации подобной функциональной возможности в текущей компоновке найдите элемент управления типа GridSplitter в библиотеке ресурсов и выберите его для дальнейшего применения. Перетаскивая экземпляр объекта типа GridSplitter на монтажный стол, привяжите его к той строке или столбцу, размеры которых вам нужно сделать изменяемыми. Ради большей наглядности разделитель сетки (т.е. объект типа GridSplitter) показан на рисунке:

Grid с изменяемыми размерами

Если вы запустите теперь свое приложение на выполнение, то сможете рисовать мышью на виртуальном полотне, доступном на первой вкладке, а также изменять размер строк сетки, используя ее разделитель. В этом случае полотно (т.е. объект типа InkCanvas) будет изменяться по высоте.

Добавление вложенной блочной панели

В завершение компоновки первой вкладки вам предстоит ввести еще несколько элементов управления в верхней области сетки, чтобы пользователь мог изменять цвет обводки и размеры пера. С этой целью добавьте элемент управления типа StackPanel в верхней строке сетки, привязав его ко всем четырем сторонам, чтобы заполнить им всю эту область. Затем установите значение Horizontal в свойстве Orientation этого элемента управления и введите в него три объекта типа Button, присвоив им имена bthRed, btnGreen и btnBlue соответственно, а также элемент управления типа Textbox, назвав его txtPenSize (текстовое поле для ввода размера пера), вместе с объектом типа Label, содержащим текст метки, описывающей данное текстовое поле.

Ниже показаны обработчики событий для кнопок, а так же обработчик события потери фокуса (Lost Focus) для Textbox:

private void ChangeColor(object sender, System.Windows.RoutedEventArgs e)
		{
			string color = ((Button)sender).Tag.ToString();
			
			this.inkCnv.DefaultDrawingAttributes.Color =
				(Color)ColorConverter.ConvertFromString(color);
		}

		private void TextBox_LostFocus(object sender, System.Windows.RoutedEventArgs e)
		{
			try
			{
				this.inkCnv.DefaultDrawingAttributes.Height = int.Parse(txtSize.Text);
				this.inkCnv.DefaultDrawingAttributes.Width = int.Parse(txtSize.Text);
			}
			catch (Exception ex)
			{
				MessageBox.Show("Возникла ошибка: " + ex.Message);
			}
		}
Рисование на виртуальном полотне разными кистями

На этом компоновка первой вкладки пользовательского интерфейса рассматриваемого здесь примера проекта завершается. Надеюсь, теперь вы будете чувствовать себя более уверенно, обращаясь с объектами типа Grid и StackPanel и заполняя их контейнеры элементами управления. Попутно вы ознакомились поближе с моделью программирования, которая поддерживается в прикладном интерфейсе WPF Ink API.

Пройди тесты
Лучший чат для C# программистов