Модификация приложения 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" 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" 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 для формы:

 

Модификация приложения 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. Добавление нового элемента – LWP 08 WPF 01

 

Добавим второе такое же окно с именем 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" Name="SpecialWindow" Icon="/LWP08WPF;component/Images/LWP08WPF01.ico">

<DockPanel Height="Auto" LastChildFill="True">

   <!--Верхняя область меню-->

   <Menu Height="20" Background="#FFA9D1F4" DockPanel.Dock="Top">

       <!--Меню Файл -->

       <MenuItem Header="Файл">

           <MenuItem Header="Сохранить как..." />

           <Separator/>

           <MenuItem Header="Выход" />

       </MenuItem>

       <!-- Меню Помощь -->

       <MenuItem Header="Помощь">

           <MenuItem Header="О программе" />

       </MenuItem>

   </Menu>

   <!-- Нижняя область строки состояния объявляется до средней области (чтобы заполнить весь низ строкой состояния)

   что не удалось бы сделать при наличии зафиксированной слева панели -->

   <StackPanel Height="31" Background="#FFCAC5C5"

       Orientation="Horizontal" DockPanel.Dock="Bottom">

       <Label Height="23" Content="Здесь находится строка состояния"

       FontFamily="Arial" FontSize="10" />

   </StackPanel>

   <!-- Левая область основного содержимого -->

   <StackPanel Height="Auto" Background="White">

       <Button Height="26" Content="Кнопка № 1" Margin="5,5,5,5" />

       <Button Height="26" Content="Кнопка № 2" Margin="5,5,5,5" />

       <Button Height="26" Content="Кнопка № 2" Margin="5,5,5,5" />

   </StackPanel>

   <!-- Правая область основного содержимого. Обратим внимания, что элемент Grid — последний дочерний элемент, поэтому он занимает всё оставшееся место -->

   <Grid Height="Auto" Background="#FFCC9393">

       <Grid.ColumnDefinitions>

           <ColumnDefinition />

           <ColumnDefinition />

       </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" />

   <TextBox x:Name="textBox1" Margin="5,5,5,5" MaxLines="60" Height="23" 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" 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"

          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" 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" Height="480">

<WrapPanel Margin="0,0,0,0" Background="White">

   <Rectangle Margin="10,10,10,10" Fill ="Blue" Height="60"/>

   <Rectangle Margin="10,10,10,10" Fill ="Blue" Height="60"/>

   <Rectangle Margin="10,10,10,10" Fill ="Blue" Height="60"/>

   <Rectangle Margin="10,10,10,10" Fill ="Blue" Height="60"/>

   <Rectangle Margin="10,10,10,10" Fill ="Blue" Height="60"/>

   <Rectangle Margin="10,10,10,10" Fill ="Blue" Height="60"/>

   <Rectangle Margin="10,10,10,10" Fill ="Blue" Height="60"/>

   <Rectangle Margin="10,10,10,10" Fill ="Blue" Height="60"/>

   <Rectangle Margin="10,10,10,10" Fill ="Blue" Height="60"/>

   <Rectangle Margin="10,10,10,10" Fill ="Blue" Height="60"/>

   <Rectangle Margin="10,10,10,10" Fill ="Blue" 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" Height="480">

<DockPanel 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" Height="480">

<Grid 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 отдаём текущий набор элементов оформления

   }

 


Дата добавления: 2019-09-13; просмотров: 181; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!