
- •1. Вводная часть
- •2. Знакомство со средой разработки на примере создания простого консольного приложения
- •3. Модификация консольного приложения
- •4. Публикация
- •5. О приложении к Лабораторной работе № 1
- •Лабораторная работа № 2: Создание простого приложения Windows Forms
- •Создание простого приложения Windows Forms
- •Модификация приложения Windows Forms
- •Завершающая часть
- •2. Создание простого приложения Windows Forms
- •3. Модификация приложения Windows Forms
- •4. Завершающая часть
- •5. О приложении к Лабораторной работе № 2
- •3. Лабораторная работа № 3: Windows Forms и использование некоторых элементов управления Лабораторная работа № 3: Windows Forms и использование некоторых элементов управления
- •Вводная часть
- •О приложении к Лабораторной работе № 3
- •1. Вводная часть
- •2. Создание приложения Windows Forms
- •3. Модификация приложения Windows Forms
- •4. Модификация приложения Windows Forms: элемент управления MenuStrip
- •5. Модификация приложения Windows Forms: элемент управления Button
- •6. Модификация приложения Windows Forms: элемент управления ToolTip
- •7. Модификация приложения Windows Forms: элемент управления ComboBox
- •8. Модификация приложения Windows Forms: элемент управления WebBrowser
- •9. Модификация приложения Windows Forms: добавляем исходный код
- •10. Завершающая часть
- •11. О приложение к Лабораторной работе № 3
- •4. Лабораторная работа № 4: Windows Forms — работа с формами Лабораторная работа № 4: Windows Forms — работа с формами
- •Вводная часть
- •О приложении к Лабораторной работе № 4
- •1. Вводная часть
- •2. Создание приложения Windows Forms
- •3. Модификация приложения Windows Forms
- •4. Модификация приложения Windows Forms: добавление новой формы
- •5. Модификация приложения Windows Forms: динамическое связывание параметров двух форм и передача параметра через прямой доступ к элементу формы
- •6. Модификация приложения Windows Forms: динамическое связывание параметров двух форм и передача параметра через передачу метода в конструктор формы
- •7. Модификация приложения Windows Forms: динамическое связывание параметров двух форм и передача параметра через класс делегата
- •8. Модификация приложения Windows Forms: динамическое связывание параметров двух форм и передача параметра через свойства
- •9. Завершающая часть
- •10. О приложении к Лабораторной работе № 4
- •5. Лабораторная работа № 5: Windows Forms — элементы управления Лабораторная работа № 5: Windows Forms — элементы управления
- •Вводная часть
- •О приложении к Лабораторной работе № 5
- •1. Вводная часть
- •2. Создание приложения Windows Forms
- •3. Модификация приложения Windows Forms
- •4. Модификация приложения Windows Forms: динамическое добавление и уничтожение элемента управления
- •5. Модификация приложения Windows Forms: стандартные диалоговые окна
- •6. Модификация приложения Windows Forms: открытие файла, сохранение файла и работа с текстом
- •7. Модификация приложения Windows Forms: прочее
- •8. Завершающая часть
- •9. О приложении к Лабораторной работе № 5
- •Лабораторная работа № 6: SolidWorks — работа с SolidWorks
- •2. Создание приложения Windows Forms
- •3. Модификация приложения Windows Forms: eDrawings 2012
- •4. Модификация приложения Windows Forms: организация работы с SolidWorks через приложение
- •5. Завершающая часть
- •6. О приложении к Лабораторной работе № 6
- •Лабораторная работа № 7: SolidWorks — использование SwCSharpAddin, работа с макросом и шаблоном детали
- •2. Создание приложения SwCSharpAddin
- •3. Модификация приложения SwCSharpAddin: макрос отрисовки болта
- •4. Модификация приложения SwCSharpAddin: построение через шаблон детали
- •5. Завершающая часть
- •6. О приложении к Лабораторной работе № 7
- •8. Лабораторная работа № 8: Создание простого приложения Windows Foundation Presentation Лабораторная работа № 8: Создание простого приложения Windows Foundation Presentation
- •Вводная часть
- •О приложении к Лабораторной работе № 8
- •1. Вводная часть
- •2. Создание приложения Windows Foundation Presentation
- •3. Модификация приложения Windows Foundation Presentation
- •4. Модификация приложения Windows Foundation Presentation: добавление нового элемента из библиотеки компонентов wpf
- •5. Модификация приложения Windows Forms: расширение функциональности приложения и работа с оформление
- •6. Модификация приложения Windows Foundation Presentation: различные возможности wpf
- •7. Модификация приложения Windows Foundation Presentation: немного о стилях и шаблонах
- •8. Завершающая часть
- •9. О приложении к Лабораторной работе № 8
- •Лабораторная работа № 9: Создание приложения-презентации Windows Foundation Presentation
- •2. Создание приложения Windows Foundation Presentation
- •3. Модификация приложения Windows Foundation Presentation
- •4. Модификация приложения Windows Foundation Presentation: работа с решением в Expression Blend
- •5. Завершающая часть
- •6. О приложении к Лабораторной работе № 9
- •Лабораторная работа № 10: Работа с базами данных — xml и ole
- •2. Создание приложения Windows Forms
- •3. Модификация приложения Windows Forms: odbc
- •4. Модификация приложения Windows Forms: ole
- •5. Модификация приложения Windows Forms: xml
- •6. Завершающая часть
- •7. О приложении к Лабораторной работе № 10
- •Лабораторная работа № 11: Динамическая связь приложений через библиотеку классов
- •2. Удалённый объект: создание библиотеки классов удалённого объекта
- •3. Клиент: создание приложения Windows Forms
- •4. Сервер: создание консольного приложения
- •5. Завершающая часть
- •6. О приложении к Лабораторной работе № 11
- •Лабораторная работа № 12: Автоматизация Microsoft Office Word
- •2. Создание приложения Windows Forms
- •3. Модификация приложения Windows Forms: создание и заполнение нового документа Microsoft Word
- •4. Модификация приложения Windows Forms: работа с шаблонами
- •5. Завершающая часть
- •6. О приложении к Лабораторной работе № 12
- •Лабораторная работа № 13: Автоматизация Microsoft Office Excel
- •2. Создание приложения Windows Forms
- •3. Модификация приложения Windows Forms: создание и заполнение нового документа Microsoft Excel
- •4. Модификация приложения Windows Forms: чтение данных с документа Microsoft Excel
- •5. Модификация приложения Windows Forms: прочие возможности Microsoft Excel
- •6. Завершающая часть
- •7. О приложении к Лабораторной работе № 13
- •Лабораторная работа № 14: Простой растровый редактор
- •2. Создание приложения Windows Forms
- •3. Модификация приложения Windows Forms: подготовка интерфейса редактора
- •4. Модификация приложения Windows Forms: функциональность растрового редактора
- •5. Завершающая часть
- •6. О приложении к Лабораторной работе № 14
- •15. Лабораторная работа № 15: Векторный редактор изображений Лабораторная работа № 15: Векторный редактор изображений
- •Вводная часть
- •О приложении к Лабораторной работе № 15
- •1. Вводная часть
- •2. Создание решения, приложения Windows Forms и библиотеки классов
- •3. Модификация приложения Windows Forms: подготовка интерфейса редактора и добавление файлов ресурсов
- •4. О будущей функциональности векторного редактора изображений
- •5. Модификация приложения Windows Forms: подготовка библиотеки классов
- •6. Модификация приложения Windows Forms: функциональность векторного редактора
- •7. Завершающая часть
- •8. О приложении к Лабораторной работе № 15
- •Лабораторная работа № 16: Windows Communication Foundation
- •2. Создание приложения wcf:
- •3. Модификация приложения wcf: приложение-клиент для wcf-службы
- •4. Создание приложения Windows Forms: сервер чата на wcf
- •5. Создание приложения Windows Forms: клиент чата на wcf
- •6. Завершающая часть
- •7. О приложении к Лабораторной работе № 16
- •Лабораторная работа № 17: Знакомство с Silverlight
- •2. Создание приложения Silverlight:
- •3. Модификация приложения Silverlight: первые шаги и полноэкранный режим
- •4. Модификация приложения Silverlight: простой проигрыватель mp3-файлов
- •5. Модификация приложения Silverlight: работа с анимацией
- •6. Завершающая часть
- •7. О приложении к Лабораторной работе № 17
- •Лабораторная работа № 18: Знакомство с asp.Net
- •2. Создание веб-приложения asp.Net
- •3. Модификация веб-приложения asp.Net: реализация различной функциональности
- •4. Модификация веб-приложения asp.Net: ajax
- •5. Завершающая часть
- •6. О приложении к Лабораторной работе № 18
- •Вводная часть
- •О приложении к Лабораторной работе № 19
- •1. Вводная часть
- •2. Создание приложения Windows Forms
- •3. Модификация приложения Windows Forms: подготовка интерфейса и добавление TabControl
- •4. Модификация приложения Windows Forms: вкладка «Просто фон!»
- •5. Модификация приложения Windows Forms: вкладка «Объекты и градиент»
- •6. Модификация приложения Windows Forms: вкладка «Мой монитор сломался!»
- •7. Модификация приложения Windows Forms: вкладка «Векторные часы»
- •8. Модификация приложения Windows Forms: вкладка «Огонь!!!»
- •9. Модификация приложения Windows Forms: вкладка «Дождик»
- •10. Завершающая часть
- •11. О приложении к Лабораторной работе № 19
- •Лабораторная работа № 20: Inventor — работа с Inventor
- •Вводная часть
- •О приложении к Лабораторной работе № 20
- •1. Вводная часть
- •2. Создание приложения Windows Forms
- •3. Модификация приложения Windows Forms: запуск и завершение приложения Inventor
- •4. Модификация приложения Windows Forms: создание новых документов
- •5. Модификация приложения Windows Forms: доступ к элементам документов Inventor
- •6. Завершающая часть
- •7. О приложении к Лабораторной работе № 20
- •Лабораторная работа № 21: Знакомство с языком f# (Эф-шарп) на примере простого приложения для командной строки
- •Вводная часть
- •О приложении к Лабораторной работе № 21
- •1. Вводная часть
- •2. Основные положения при работе с f#
- •3. Создание приложения «Учебник по f#»
- •4. Создание консольного приложения
- •5. О приложении к Лабораторной работе № 21
- •Лабораторная работа № 22: Различные примеры на f#
- •2. Создание приложения «Приложение f#»
- •3. Модификация приложения f#: match
- •4. Модификация приложения f#: создание форм и рисование объектов на форме
- •5. Модификация приложения f#: работа с базой данных Microsoft Access
- •6. О приложении к Лабораторной работе № 22
- •23. Дополнительная лабораторная работа № 1
- •24. Дополнительная лабораторная работа № 2
- •25. Дополнительная лабораторная работа № 3
- •Вводная часть
- •1. Вводная часть
- •2. Создание приложения Windows Foundation Presentation
- •3. Модификация приложения Windows Foundation Presentation: добавление ресурсов
- •4. Модификация приложения Windows Foundation Presentation: добавление исходного кода
- •5. Модификация приложения Windows Foundation Presentation: оформление элемента ListBox
- •6. Завершающая часть
- •7. О приложении к данной работе
5. Модификация приложения Windows Forms: расширение функциональности приложения и работа с оформление
Такой мощный инструмент как WPF просто нельзя не применить сейчас. Например возможности по оформление одной лишь кнопки просто безграничны. Начнём пожалуй с самой формы.
Модифицируем XAML-код формы следующим образом и откомпилируем приложение:
<Window x:Class="LWP08WPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Простое приложение WPF (C#)" mc:Ignorable="d" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" Height="350" Width="525" WindowStyle="SingleBorderWindow" ToolTip="Главное окно" ResizeMode="CanResizeWithGrip" Name="Main" ForceCursor="False" Icon="/LWP08WPF;component/Images/LWP08WPF.ico">
<Grid>
<InkCanvas HorizontalAlignment="Stretch" Margin="12,12,12,199" Name="inkCanvas1" VerticalAlignment="Stretch" MinHeight="100" EditingMode="Ink" Background="LightYellow" />
<Button Content="Очистить" HorizontalAlignment="Right" Margin="0,0,12,170" Name="button1" VerticalAlignment="Bottom" Width="75" Click="button1_Click" Height="23" />
</Grid>
<Window.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFD08E8E" Offset="0" />
<GradientStop Color="#FF881E1E" Offset="0.99" />
</LinearGradientBrush>
</Window.Background>
</Window>
Комментарии расставляем при необходимости следующим образом (<!-- Текст комментария -->):
Рис. 5. 1. Комментарии в коде XAML и добавление комментария через IntelliSense
Новый вид приложения (с новым кодом XAML):
Рис. 5. 2. Градиент для фона окна приложения
Фактически установка градиента выполняется изменением свойства Background для формы:
6. Модификация приложения Windows Foundation Presentation: различные возможности wpf
Расширим
возможности приложения. Расставим в
главном окне (MainWindow.xaml)
новые элементы: один групповой элемент
Expander
(
),
реализующий скрытие и показ элементов
находящихся внутри этого элемента; одну
кнопку в левом нижнем углу. Внутри
элемента Expander
размести одну кнопку и 5 переключателей
типа RadioButton.
Рис. 6. 1. Новые элементы в окне формы MainWindow.xaml
Имена элементов управления оставляем по умолчанию (имя элемента в этом случае задаётся как <тип элемента>[следующий номер элемента на форме]).
Свойства элемента Expander (группа свойств Общее):
ExpandDirection: |
Up |
^ Реализует направление раскрытия содержимого элемента. Установим раскрытие «вверх».
Header: |
Выберите оформление |
Кнопка в главном меню слева (Button):
Имя (первое свойство элемента Button): |
button7 |
Content: |
Команды без событий |
Переключатели RadioButton группового элемента Expander:
Имя (первое свойство элемента RadioButton): |
radioButton1 |
Content: |
Canvas |
Имя (первое свойство элемента RadioButton): |
radioButton2 |
Content: |
StackPanel |
Имя (первое свойство элемента RadioButton): |
radioButton3 |
Content: |
WrapPanel |
Имя (первое свойство элемента RadioButton): |
radioButton4 |
Content: |
DockPanel |
Имя (первое свойство элемента RadioButton): |
radioButton5 |
Content: |
Всё |
Кнопка группового элемента Expander:
Имя (первое свойство элемента Button): |
Button2 |
Content: |
Сменить оформление |
Теперь
добавим две новые формы (в качестве окна
Window).
Для этого выделим правой кнопкой мыши
название проекта в обозревателе решений
(
),
далее выполним Добавить
-> Создать
элемент…
(Ctrl+Shift+A).
Выберем Окно
(WPF),
введём Имя:
Special.xaml:
Рис. 6. 2. Добавление нового элемента – LWP08WPF01
Добавим второе такое же окно с именем NoEventsWindow.xaml, в итоге получим:
Теперь заполним окна элементами. Для этого можно просто вставить код XAML для определённого окна. Код для окна Special.xaml:
<Window x:Class="LWP08WPF01.Special"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Простое приложение WPF (C#) :: Специальное окно" Height="480" Width="480" Name="SpecialWindow" Icon="/LWP08WPF;component/Images/LWP08WPF01.ico">
<DockPanel Width="Auto" Height="Auto" LastChildFill="True">
<!--Верхняя область меню-->
<Menu Width="Auto" Height="20" Background="#FFA9D1F4" DockPanel.Dock="Top">
<!--Меню Файл -->
<MenuItem Header="Файл">
<MenuItem Header="Сохранить как..." />
<Separator/>
<MenuItem Header="Выход" />
</MenuItem>
<!-- Меню Помощь -->
<MenuItem Header="Помощь">
<MenuItem Header="О программе" />
</MenuItem>
</Menu>
<!-- Нижняя область строки состояния объявляется до средней области (чтобы заполнить весь низ строкой состояния)
что не удалось бы сделать при наличии зафиксированной слева панели -->
<StackPanel Width="Auto" Height="31" Background="#FFCAC5C5"
Orientation="Horizontal" DockPanel.Dock="Bottom">
<Label Width="155" Height="23" Content="Здесь находится строка состояния"
FontFamily="Arial" FontSize="10" />
</StackPanel>
<!-- Левая область основного содержимого -->
<StackPanel Width="136" Height="Auto" Background="White">
<Button Width="Auto" Height="26" Content="Кнопка № 1" Margin="5,5,5,5" />
<Button Width="126" Height="26" Content="Кнопка № 2" Margin="5,5,5,5" />
<Button Width="126" Height="26" Content="Кнопка № 2" Margin="5,5,5,5" />
</StackPanel>
<!-- Правая область основного содержимого. Обратим внимания, что элемент Grid — последний дочерний элемент, поэтому он занимает всё оставшееся место -->
<Grid Width="Auto" Height="Auto" Background="#FFCC9393">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!-- Рисуем квадраты -->
<Rectangle Fill="LightCyan" Margin="10,10,10,10" Grid.Row="0" Grid.Column="0" />
<Rectangle Fill="LightCyan" Margin="10,10,10,10" Grid.Row="0" Grid.Column="1" />
<Rectangle Fill="LightCyan" Margin="10,10,10,10" Grid.Row="1" Grid.Column="0" />
<Rectangle Fill="LightCyan" Margin="10,10,10,10" Grid.Row="1" Grid.Column="1" />
</Grid>
</DockPanel>
</Window>
Абсолютно
весь этот генерируется при ручной
расстановке элементов (последовательном
размещении) на форме и изменении
необходимых свойств (какие именно,
написано в коде, и теперь их можно
просмотреть в окне свойств: те, что
заданы имеют значок
).
Тут же, после вставки кода сформируется окно в конструкторе:
Рис. 6. 3. Конструктор окна Special.xaml
Сформируем окно NoEventsWindow.xaml:
<Window x:Class="LWP08WPF01.NoEventsWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Приложение WPF (C#) :: Работа с командами без событий" Height="179" Width="500"
ResizeMode="NoResize"
WindowStartupLocation="CenterScreen" Name="SimpleEditor" Icon="/LWP08WPF;component/Images/LWP08WPF01.ico">
<StackPanel Orientation="Vertical" Width="auto">
<StackPanel Orientation="Horizontal" Background="Gainsboro" Margin="10" Height="40">
<Button Command="Cut" CommandTarget="{Binding ElementName=textBox1}" Margin="5,5,5,5" Content ="Вырезать"/>
<Button Command="Copy" CommandTarget="{Binding ElementName=textBox1}" Margin="5,5,5,5" Content="Копировать"/>
<Button Command="Paste" CommandTarget="{Binding ElementName=textBox1}" Margin="5,5,5,5" Content="Вставить"/>
<Button Command="Undo" CommandTarget="{Binding ElementName=textBox1}" Margin="5,5,5,5" Content="Откат"/>
<Button Command="Redo" CommandTarget="{Binding ElementName=textBox1}" Margin="5,5,5,5" Content="Вернуть"/>
</StackPanel>
<TextBlock HorizontalAlignment="Left" Margin="5,5,5,5" Text="Введите текст, попробуйте воспользоваться командами. Выделите текст, посмотрите какие кнопки (команды) станут активными" TextWrapping="Wrap" Height="Auto" Width="Auto" />
<TextBox x:Name="textBox1" Margin="5,5,5,5" MaxLines="60" Height="23" Width="470" Background="#FFF9EBA9" VerticalContentAlignment="Bottom" />
</StackPanel>
</Window>
Обратим внимание, что для элемента TextBlock форматирование в окне XAML влияет на отображение текста в конструкторе.
Рис. 6. 4. Конструктор окна NoEventsWindow.xaml
Перед
тем как добавлять код событий и
компилировать приложение немного
расскажем про то, что мы здесь делаем.
Наше приложение при помощи переключателей
RadioButton в группе Выберите оформление
должно инициализировать выбранный
переключателем элемент, создавать новый
объект и загружать в него новое оформление,
после чего изменять оформление главного
окна, демонстрируя работу определённого
элемента управления. Первый такой
элемент это Canvas
(
).
Canvas— один из удобнейших элементов управления макета. Это простой контейнер положений X и Y. Чтобы располагаться в родительском элементе Canvas, каждый из его дочерних элементов должен задавать следующие четыре свойства:
Canvas.Left
Canvas.Right
Canvas.Top
Canvas.Bottom
Если эти четыре свойства заданы, элемент управления будет располагаться в родительском элементе управления Canvas с учётом этих значений. Эти свойства выглядят несколько странно, например Canvas.Left. Это не обычные свойства, используемые в платформе .NET 2.0, а присоединённые свойства зависимости.
Если элемент Canvas — простой контейнер положений X и Y, что происходит с наложением двух элементов управления и какой дочерний элемент будет находиться на переднем плане? Всё это контролируется ещё одним присоединённым свойством зависимости элемента управления Canvas. Это свойство под названием Canvas.ZIndex определяет, какой элемент управления должен находиться сверху. Как правило, чем больше значение Canvas.ZIndex, тем выше элемент управления, который задаёт это присоединенное свойство зависимости. Если свойство Canvas.ZIndex не задано ни для одного дочернего элемента, оно будет задаваться в порядке добавления дочерних элементов в элемент Canvas.
Нажатие кнопки (для radioButton1: Canvas) будет выполнять создание этого элемента через код C#. XAML-представление (аналог) кода будет таким:
<Window x:Class="LWP08WPF01.CanvasSpecial"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Приложение WPF (C#) :: Canvas" Width="640" Height="480">
<Canvas Margin="0,0,0,0" Background="White">
<Rectangle Fill="Red"
Stroke="Red"
Width="145"
Height="126"
Canvas.Left="124" Canvas.Top="122"/>
<Ellipse Fill="Blue"
Stroke="Blue"
Width="121" Height="100"
Panel.ZIndex="1"
Canvas.Left="195" Canvas.Top="191"/>
</Canvas>
</Window>
Второй
элемент
это
StackPanel
(
).
Он
располагает своё содержимое по вертикали
или горизонтали в зависимости от значения
свойства Orientation.
<Window x:Class="LWP08WPF01.StackPanelSpecial"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Приложение WPF (C#) :: StackPanel" Width="640" Height="480">
<StackPanel Margin="0,0,0,0" Background="White" Orientation="Vertical">
<Button Content="Кнопка сверху"/>
<Button Content="Кнопка снизу"/>
</StackPanel>
</Window>
WarpPanel
(
),
также очень просто использовать он
просто «оборачивает» своё содержимое.
<Window x:Class="LWP08WPF01.WrapPanelSpecial"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Приложение WPF (C#) :: WrapPanel" Width="640" Height="480">
<WrapPanel Margin="0,0,0,0" Background="White">
<Rectangle Margin="10,10,10,10" Fill ="Blue" Width="60" Height="60"/>
<Rectangle Margin="10,10,10,10" Fill ="Blue" Width="60" Height="60"/>
<Rectangle Margin="10,10,10,10" Fill ="Blue" Width="60" Height="60"/>
<Rectangle Margin="10,10,10,10" Fill ="Blue" Width="60" Height="60"/>
<Rectangle Margin="10,10,10,10" Fill ="Blue" Width="60" Height="60"/>
<Rectangle Margin="10,10,10,10" Fill ="Blue" Width="60" Height="60"/>
<Rectangle Margin="10,10,10,10" Fill ="Blue" Width="60" Height="60"/>
<Rectangle Margin="10,10,10,10" Fill ="Blue" Width="60" Height="60"/>
<Rectangle Margin="10,10,10,10" Fill ="Blue" Width="60" Height="60"/>
<Rectangle Margin="10,10,10,10" Fill ="Blue" Width="60" Height="60"/>
<Rectangle Margin="10,10,10,10" Fill ="Blue" Width="60" Height="60"/>
</WrapPanel>
</Window>
DockPanel
(
).
Элемент управления DockPanel — один из самых
полезных элементов управления макета.
Он, вероятно, будет использоваться как
базовый в каждом новом окне.
По сути, с помощью DockPanel (или двух таких элементов) можно реализовать основной макет большинства современных приложений. Можно закрепить строку меню сверху, затем левую и правую области основного содержимого, а строку состояния снизу. И всё это благодаря паре свойств элемента управления DockPanel. Как правило, закрепление любого дочернего элемента в элементе DockPanel управляется следующим присоединенным свойством зависимости:
DockPanel.Dock
Этому свойству можно присвоить значения Left, Right, Top или Bottom. Есть ещё одно полезное свойство (обычное свойство CLR) элемента управления DockPanel, называемое LastChildFill. Если этому свойству присвоено значение true, последний добавленный дочерний элемент будет занимать всё оставшееся свободное пространство. Оно переопределяет свойство DockPanel.Dock, которое может быть уже задано дочерним элементом.
Окно реализующее панель меню и свойство описанное выше, в XAML-коде выглядит так:
<Window x:Class="LWP08WPF01.DockPanelSpecial"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Приложение WPF (C#) :: DockPanel" Width="640" Height="480">
<DockPanel Width="Auto" Height="Auto" LastChildFill="True">
<Rectangle Fill="CornflowerBlue" Stroke="CornflowerBlue" Height="20" DockPanel.Dock="Top"/>
<Rectangle Fill="Orange" Stroke="Orange" />
</DockPanel>
</Window>
Элемент
Grid
(
)
— самый сложный элемент управления
макета в WPF. Он немного похож на табличный
элемент управления HTML,
в котором можно задавать строки и
столбцы, а ячейки могут содержать
несколько строк или столбцов. Для свойств
Width
и Height
столбцов и строк может применяться
странный синтаксис с использованием
символа звездочки (*), предоставляемый
с помощью класса GridLength.
Его можно представить в виде процентного
разделителя свободного места. Рассмотрим
следующую разметку:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
Здесь в элементе Grid объявлены три элемента ColumnDefinition. Ширина первого элемента ColumnDefinition зафиксирована (40 пикселей), а оставшееся пространство делится между двумя другими элементами ColumnDefinition, причем последнему из них выделяется в два раза больше места, чем предпоследнему. Этот же принцип применяется в отношении RowDefinition.
Для уведомления системы макета WPF о ячейке, к которой относятся дочерние элементы элемента Grid, используются следующие присоединенные свойства зависимости (нумерация индекса начинается с 0):
Grid.Column
Grid.Row
А для задания количества строк или столбцов, занимаемых ячейкой, используются следующие присоединенные свойства зависимости (значения начинаются с 1):
Grid.ColumnSpan
Grid.RowSpan
При умелом использовании элемента управления Grid можно имитировать практически любые другие элементы управления макета. Пример окна с тремя панелями реализованного через Grid:
<Window x:Class="LWP08WPF01.GridSpecial"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Приложение WPF (C#) :: Grid" Width="640" Height="480">
<Grid Width="Auto" Height="Auto" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<Rectangle Fill="Aqua" Grid.Column="0" Grid.Row="0"/>
<Rectangle Fill="Plum" Grid.Column="1" Grid.ColumnSpan="2"/>
</Grid>
</Window>
Некоторые панели могут быть связаны с данными, поэтому иногда на панели может отображаться слишком много дочерних элементов. Например, если элемент StackPanel содержит элемент ListBox, привязанный к большому запросу базы данных. В этом случае в списке будет множество элементов, то есть у элемента ListBox будет множество дочерних элементов. Однако по умолчанию в элементе ListBox используется вертикальный элемент StackPanel для обработки своих элементов. В платформе WPF доступен ещё один прием, который может помочь в этой ситуации. Присоединённое свойство зависимости VirtualizingStackPanel.IsVirtualizing в элементе ListBox обеспечит виртуализацию отображения элементов внутреннего элемента управления StackPanel в элементе ListBox. Но что такое этот элемент VirtualizingStackPanel?
Виртуализация панели означает, что создаются только видимые элементы. Остальные элементы не отображаются. Рассмотрим создание элемента ListBox с изображениями, привязанного к базе данных, содержащей 100 500 строк... На загрузку такого элемента уйдёт очень много времени. Если используется виртуализированная панель, в интерфейсе пользователя будут созданы только видимые изображения. При прокрутке списка элементы, видимые в данный момент, будут уничтожаться, а новые видимые элементы загружаться в интерфейс пользователя. Только одна панель поддерживает виртуализацию, и это панель VirtualizingStackPanel. Новые панели виртуализации необходимо разрабатывать самостоятельно.
Теперь немного про окно NoEventsWindows.xaml и перенаправление команд.
Система команд WPF построена на основе классов RoutedCommand и RoutedEvent. От простого обработчика событий, присоединённого к кнопке или таймеру, команды отличаются тем, что они отделяют семантику и инициатор действия от логики. Это позволяет вызывать для нескольких разнородных источников одну и ту же логику команды, а также настраивать её для различных целевых объектов. Примерами команд служат операции редактирования Копировать, Вырезать и Вставить, доступные во многих приложениях. Семантика команды унифицирована для различных приложений и классов, однако логика действия специфична для конкретного объекта. Сочетание клавиш Ctrl+X вызывает команду Вырезать в классах текста, классах изображений и веб-браузерах. Однако фактическая логика выполнения этой операции определяется объектом или приложением, в котором она выполняется, а не источником, в котором она вызывается. В текстовом объекте можно вырезать и поместить выделенный текст в буфер обмена. В графическом объекте можно вырезать выделенное изображение. Однако для вызова команды в обоих классах может использоваться один и тот же источник команды, например объект KeyGesture или кнопка на панели инструментов. В платформах .NET3.0/3.5/4.0 предусмотрено множество готовых команд для выполнения типичных задач.
Класс ApplicationCommands содержит такие команды, как вырезание, копирование и вставка.
Класс MediaCommands содержит такие команды, как Усиление баса, Следующий канал, Предыдущий канал и Отключение звука.
Класс NavigationCommands содержит такие команды, как Назад, Вперёд и Избранное.
Класс ComponentCommands содержит такие команды, как Вниз, Фокус на страницу вверх и В конец.
Класс EditingCommands содержит такие команды, как Выровнять по центру, Возврат и Удалить.
Полный список команд, если нужно, можно посмотреть в библиотеке MSDN (http://msdn.microsoft.com/ru-ru/ms348103).
С помощью встроенных команд можно реализовать довольно сложную функциональность без процедурного кода.
Закончим построение приложение добавив все обработички. Кнопка Команды без событий, событие Click:
private void button7_Click(object sender, RoutedEventArgs e)
{
NoEventsWindow Window = new NoEventsWindow();
Window.Show();
}
Кнопка Сменить оформление:
private void button2_Click(object sender, RoutedEventArgs e)
{
if (radioButton1.IsChecked == true)
{
Canvas Canv = new Canvas(); // Создаём экземпляр объекта Canvas
// Добавить элемент Canvas в качестве единственного дочернего элемента Window
this.Content = Canv;
Canv.Margin = new Thickness(0, 0, 0, 0); // Создаём поле расстояния до ближайшего элемента. Так как ближайшего элемента нет, Canvas заполняет всю форму
Canv.Background = new SolidColorBrush(Colors.White); // Задаём фон
// Прямоугольник
Rectangle r = new Rectangle();
r.Fill = new SolidColorBrush(Colors.Blue); // Заливка прямоугольник
r.Stroke = new SolidColorBrush(Colors.Red); // Граница прямоугольника
r.Width = 145; // Ширина прямоугольника
r.Height = 126; // Высота прямоугольника
r.SetValue(Canvas.LeftProperty, (double)124); // Устанавливаем левую верхнюю границу прямоугольника
r.SetValue(Canvas.TopProperty, (double)122); // Устанавливаем верхнюю границу первого элемента
Canv.Children.Add(r); // Добавляем прямоугольник в качестве дочернего для Canvas
// Эллипс
Ellipse el = new Ellipse();
el.Fill = new SolidColorBrush(Colors.Green);
el.Stroke = new SolidColorBrush(Colors.Green);
el.Width = 121;
el.Height = 100;
el.SetValue(Canvas.ZIndexProperty, 1);
el.SetValue(Canvas.LeftProperty, (double)195);
el.SetValue(Canvas.TopProperty, (double)191);
Canv.Children.Add(el);
// Кнопка Вернуть оформление
Button button3 = new Button();
button3.Content = "Вернуть оформление";
button3.Width = 131;
button3.Height = 23;
button3.HorizontalAlignment = HorizontalAlignment.Right;
button3.VerticalAlignment = VerticalAlignment.Bottom;
button3.Margin = new Thickness(12, 12, 12, 12); // Кнопка будет распологаться в левом верхнем углу
button3.Click += new RoutedEventHandler(button3_Click); // Переопределяем события для кнопки
Canv.Children.Add(button3);
}
if (radioButton2.IsChecked == true)
{
StackPanel SP = new StackPanel();
// Добавить элемент StackPanel в качестве единственного дочернего элемента Window
this.Content = SP;
SP.Margin = new Thickness(0, 0, 0, 0);
SP.Background = new SolidColorBrush(Colors.White);
SP.Orientation = Orientation.Vertical;
// Кнопка 1
Button b1 = new Button();
b1.Content = "Кнопка сверху";
SP.Children.Add(b1);
// Кнопка 2
Button b2 = new Button();
b2.Content = "Кнопка снизу";
SP.Children.Add(b2);
// Кнопка Вернуть оформление
Button button4 = new Button();
button4.Content = "Вернуть оформление";
button4.Width = 131;
button4.Height = 23;
button4.HorizontalAlignment = HorizontalAlignment.Right;
button4.VerticalAlignment = VerticalAlignment.Bottom;
button4.Margin = new Thickness(12, 12, 12, 12); // Кнопка будет располагаться справа вверху под "Кнопка внизу"
button4.Click += new RoutedEventHandler(button3_Click);
SP.Children.Add(button4);
}
if (radioButton3.IsChecked == true)
{
WrapPanel WP = new WrapPanel();
// Добавить элемент WrapPanel в качестве единственного дочернего элемента Window
this.Content = WP;
WP.Margin = new Thickness(0, 0, 0, 0);
WP.Background = new SolidColorBrush(Colors.White);
// Добавить прямоугольники (создание одинаковых объектов)
Rectangle r;
for (int i = 0; i <= 10; i++)
{
r = new Rectangle();
r.Fill = new SolidColorBrush(Colors.Blue);
r.Margin = new Thickness(10, 10, 10, 10);
r.Width = 60;
r.Height = 60;
WP.Children.Add(r);
}
// Кнопка Вернуть оформление
Button button5 = new Button();
button5.Content = "Вернуть оформление";
button5.Width = 131;
button5.Height = 23;
button5.HorizontalAlignment = HorizontalAlignment.Right;
button5.VerticalAlignment = VerticalAlignment.Bottom;
button5.Margin = new Thickness(12, 12, 12, 12); // Кнопка будет рсполагаться слева вверху под всеми элементами
button5.Click += new RoutedEventHandler(button3_Click);
WP.Children.Add(button5);
}
if (radioButton4.IsChecked == true)
{
DockPanel DP = new DockPanel();
DP.LastChildFill = true;
// Это эквивалентно Width = "Auto" в XAML, кроме элементов GridColumn Width/Height и GridRow Width/Height
DP.Width = Double.NaN;
DP.Height = Double.NaN;
// Добавить элемент WrapPanel в качестве единственного дочернего элемента Window
this.Content = DP;
// Добавить прямоугольник (верхний)
Rectangle rTop = new Rectangle();
rTop.Fill = new SolidColorBrush(Colors.CornflowerBlue);
rTop.Stroke = new SolidColorBrush(Colors.CornflowerBlue);
rTop.Height = 20;
DP.Children.Add(rTop);
// Добавить прямоугольник (нижний)
rTop.SetValue(DockPanel.DockProperty, Dock.Top);
Rectangle rFill = new Rectangle();
rFill.Fill = new SolidColorBrush(Colors.Orange);
rFill.Stroke = new SolidColorBrush(Colors.Orange);
rFill.Height = 20;
DP.Children.Add(rFill);
rFill.SetValue(DockPanel.DockProperty, Dock.Bottom);
// Кнопка Вернуть оформление
Button button6 = new Button();
button6.Content = "Вернуть оформление";
button6.Width = 131;
button6.Height = 23;
button6.HorizontalAlignment = HorizontalAlignment.Right;
button6.VerticalAlignment = VerticalAlignment.Bottom;
button6.Margin = new Thickness(12, 12, 12, 12); // Кнопка будет располагаться между верхним и нижним прямоугольником
button6.Click += new RoutedEventHandler(button3_Click);
DP.Children.Add(button6);
}
if (radioButton5.IsChecked == true)
{
Special Window = new Special();
Window.Show();
}
}
Теперь организуем событие нажатия виртуальной кнопки Вернуть оформление:
private void button3_Click(object sender, RoutedEventArgs e)
{
this.Content = Default; // Возвращаем первоначальное оформление
}
И добавим код для сохранения оформления в главном окне (модифицируем код как показано ниже):
public partial class MainWindow : Window
{
Object Default = new Object(); // Инициализируем контейнер для первоначального оформления
public MainWindow()
{
InitializeComponent();
Default = this.Content; // Объекту Default отдаём текущий набор элементов оформления
}