Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Wpf-АК11.doc
Скачиваний:
6
Добавлен:
01.03.2025
Размер:
3 Мб
Скачать
☆

Задание к лабораторной работе

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

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

Варианты индивидуальных заданий

1. Программа просмотра 4 веб-страниц одновременно. Выбор типа разметки предлагается выбрать самостоятельно, мотивировав свой выбор.

2. Программа для просмотра фотографий и альбомов. В левой части окна приложения приведен список альбомов, в правой – его содержимое.

3. Программа для отображения погодных сводок. Интерфейс программы подразумевает выведение на экран температуры, скорости и направления ветра, влажности, солнечности на 5 календарных дней (статическим изображением). Необходимо использовать различные вложенные типы разметок.

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

5. Программа для работы с мобильным устройством. Интерфейс программы должен содержать изображение подключенного мобильного устройства, его имя, серийный номер (левая часть окна приложения), а также список файлов, доступных для чтения и записи (правая часть). Также рекомендуется добавить палень управления файлами на устройстве.

Контрольные вопросы

1. Что такое макет в WPF?

2. Зачем используется компонент Canvas?

3. Чем отличаются приведенные в лабораторной работе типы разметки интерфейса, и при каких обстоятельствах следует использовать каждый из них?

Лабораторная работа 4

Xaml и код, расширения разметки и ресурсы

Цель: получить практические навыки работы с WPF средствами языка программирования C#.

План лабораторного занятия:

  1. XAML и MVC

  2. Ссылки на ресурсы в WPF

Теоретически сведения

1. XAML и MVC

В общем смысле платформу WPF можно отнести к шаблону типа квази-MVC (Model-View-Controller, модель — представление — поведение). Хотя модель и поведение объединены, разделение кода XAML и кода программной части отлично отделяет представление от логики кода программной части так же, как в платформе ASP.NET. Это не классический шаблон MVC, но благодаря XAML представление действительно отделено.

Рекомендуется делать в XAML следующие:

  • фактическая разметка, представляющая интерфейс пользователя;

  • добавление необходимых файлов ресурсов;

  • добавление локальных ресурсов;

  • возможное объявление привязок команд.

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

  • вся обработка событий;

  • циклы, вычисления и вызовы других промежуточных методов классов, не относящихся напрямую к интерфейсу пользователя;

  • проверки;

  • обработка исключений, отсутствующая в XAML вследствие его декларативного характера;

  • рекурсивные операции.

В сущности, интерфейс пользователя (XAML) должен только представлять данные, все остальное должно делаться в коде программной части.

Как ссылаться на классы и сборки в XAML. Для реалиизации ссылки в XAML на собственные классы и элементы управления или даже классы и элементы управления из другой сборки .NET. нужно выполнить следущее:

using System.Windows.Controls

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

Рассмотрим четыре примера.

  1. Ииспользование локального (из этого же пространства имен) элемента управления в элементе Window.

  2. Использование локального (из этого же пространства имен) класса в элементе Window.

  3. Использование внешнего (из другого пространства имен или другой сборки) элемента управления в элементе Window.

  4. Использование внешнего (из другого пространства имен или другой сборки) класса в элементе Window.

Использование локального (из этого же пространства имен) элемента управления в элементе Window. Это самый простой из четырех способов ссылки на классы в XAML. Поскольку класс, на который требуется ссылаться, находится в том же пространстве имен, достаточно добавить объявление пространства имен xmlns: в открывающий тег элемента Window (обратите внимание, я использовал элемент Window, но это мог быть элемент Frame или любой другой, где можно размещать другие элементы).

Допустим, что в текущем приложении (рис. 4.1) WPF_Tour_Beginners_Part_2, а у сгенерированной сборки то же имя. В этом же пространстве имен есть элемент типа UserControl с именем UserConrtrol2.

Рис. 4.1 - Сборки приложения

Можно использовать следующее объявление пространства имен xmlns: в открывающем теге элемента Window:

xmlns:local="clr-namespace:WPF_Tour_Beginners_Part_2;assembly="

Это позволит использовать в разметке XAML элемент UserControl с именем UserConrtrol2 следующим образом:

<!-- Ссылка на сборку 1. Это объявление класса, который не входит в стандартное пространство имен Microsoft.

    Объявление xmlns: в верхней части файла можно использовать для ссылок на локальную (имя local:

    означает это же пространство имен) или другую библиотеку Dll. Ниже описывается, как определять xmlns:.

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

    требуется только пространство имен. Обратите внимание, что строка clr-namespace/assembly вводится С УЧЕТОМ РЕГИСТРА.

   Этот элемент управления входит в текущее пространство имен или текущую сборку.

-->

<local:UserControl2/>

Может возникнуть вопрос, почему использовано слово local в объявлении xmlns: в элементе Window. Конечно, можно использовать любое имя, но имя local: используется во многих книгах и де-факто стало обозначением для объектов из этого же пространства имен.

Использование локального (из этого же пространства имен) класса в элементе Window. В этом случае необходимы практически те же действия, что и для локального элемента UserControl. Единственное отличие в том, что элемент управления UserControl — визуальный объект WPF (как правило, он наследуется от элементов Visual или Visual3D), то есть он может использоваться в интерфейсе пользователя. Классы могут наследоваться от элементов Visual или Visual3D, а могут и не наследоваться, поэтому они могут быть, а могут и не быть объектами интерфейса пользователя. Если они не наследуются от Visual или Visual3D, в разметке интерфейса их использовать нельзя, но в качестве ресурсов — можно. Мы еще не обсуждали ресурсы, поэтому пока вам просто придется принять на веру тот факт, что мы можем создать экземпляр класса, разместив ссылку на него в разделе ресурсов или в файле ресурсов файла XAML.

Допустим, что в текущем приложении (рис. 4.2) пространство имен WPF_Tour_Beginners_Part_2, а у сгенерированной сборки то же имя. А также что в этом пространстве имен есть пользовательский класс LocalClass.

Рис. 4.2 - Сборки приложения

Как и раньше, можно использовать следующее объявление пространства имен xmlns: в открывающем теге элемента Window:

xmlns:local="clr-namespace:WPF_Tour_Beginners_Part_2;assembly="

Это позволит использовать пользовательский класс LocalClass в разметке XAML в виде ресурса.

<StackPanel x:Name="sp1" Orientation="Vertical">

   <!--Я добавил эту строку только для того, чтобы продемонстрировать возможность добавления классов в разметку XAML. Использованные мною классы

        не могут входить в интерфейс пользователя, поскольку они не являются элементами управления интерфейса (не наследуются от класса Visual).

       Поэтому я поместил их в словарь ресурсов.

        -->

   <StackPanel.Resources>

       <!-- Ссылка на сборку 2. В разметке XAML можно использовать локальные классы (из этого же пространства имен) при условии, что

            объявление xmlns: вверху этого файла является корректным -->

       <local:LocalClass x:Key="localClass1" AnIntProp="5"/>

   </StackPanel.Resources>

</StackPanel>

Мысоздалиэкземпляркласса LocalClass в XAML иприсвоилиегосвойству AnIntProp значение 5. Обратите внимание, что для создания экземпляра класса в XAML в исходном классе должен быть конструктор без параметров.

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

Рис. 4.3 - Использование ресурса

Использование внешнего (из другого пространства имен или другой сборки) элемента управления в элементе Window.В этом случае необходимы практически те же действия, что и для локального элемента UserControl. Единственное отличие в том, что элемент управления UserControl, который мы пытаемся использовать в текущем объекте Window, фактически находится в другой сборке (в демонстрационном приложении используется сборка SeperateWPFUserControl_Dll). Очевидно, необходимо ссылаться на эту сборку SeperateWPFUserControl_Dll.

Единственное изменение объявления пространства имен xmlns: заключается в добавлении имени Assembly.

Предположим, что в текущем приложении (рис. 4.4) пространство имен WPF_Tour_Beginners_Part_2, и мы пытаемся ссылаться на сборку сторонних разработчиков (SeperateWPFUserControl_Dll в демонстрационном приложении), а эта сборка содержит элемент управления UserControl с именем UserControl1.

Рис. 4.4 - Сборки приложения

Можно использовать следующее объявление пространства имен xmlns: в открывающем теге элемента Window, но в этот раз необходимо включить также имя сборки:

xmlns:SeperateWPFUserControlDll="clr-namespace:SeperateWPFUserControl_Dll;assembly=SeperateWPFUserControl_Dll"

Это позволит использовать в разметке XAML элемент UserControl с именем UserConrtrol1 следующим образом:

<!-- Ссылка на сборку 3. Это объявление класса, который не входит в стандартное пространство имен Microsoft.

    Объявление xmlns: в верхней части файла можно использовать для ссылок на локальную (имя local:

    означает это же пространство имен) или другую библиотеку Dll. Ниже описывается, как определять xmlns:.

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

    требуется только пространство имен. Обратите внимание, что строка clr-namespace/assembly вводится С УЧЕТОМ РЕГИСТРА.

   Этот элемент управления входит в пространство имен SeperateWPFUserControl_Dll и сборку SeperateWPFUserControl_Dll.dll.

-->

<SeperateWPFUserControlDll:UserControl1/>

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

Использование внешнего (из другого пространства имен или другой сборки) класса в элементе Window. В этом случае необходимы практически те же действия, что и для локального класса. Единственное отличие в том, что будут использоваться классы из некоторых основных сборок .NET, но принцип остается таким же.

Предположим, что в XAML требуется использовать следующие классы:

  • System.Collections.Hashtable всборке mscorlib.dll;

  • System.Int32 всборке mscorlib.dll.

Как и раньше, можно использовать следующее объявление пространства имен xmlns: в открывающем теге элемента Window:

   xmlns:collections="clr-namespace:System.Collections;assembly=mscorlib"

   xmlns:sys="clr-namespace:System;assembly=mscorlib"

Это позволит использовать эти классы в разметке XAML в виде ресурсов.

<StackPanel x:Name="sp1" Orientation="Vertical">

   <!--Я добавил эту строку только для того, чтобы продемонстрировать возможность добавления классов в разметку XAML. Использованные мною классы

        не могут входить в интерфейс пользователя, поскольку они не являются элементами управления интерфейса (не наследуются от класса Visual).

       Поэтому я поместил их в словарь ресурсов.

        -->

   <StackPanel.Resources>

       <!-- Ссылка на сборку 4. В разметке XAML можно использовать даже стандартные классы из пространства имен System при условии, что

            объявление xmlns: вверху этого файла является корректным -->

       <collections:Hashtable x:Key="ht1">

           <sys:Int32 x:Key="key1">1</sys:Int32>

           <sys:Int32 x:Key="key2">2</sys:Int32>

       </collections:Hashtable>

   </StackPanel.Resources>

</StackPanel>

Это очень похоже на то, что мы видели в примере с локальным классом.

Расширения разметки. Расширения разметки увеличивают возможности выражений XAML. Строка расширения разметки может обрабатываться во время выполнения. На основании этой строки создается соответствующий объект. Расширения разметки реализуются в XAML явно и единообразно.

Если значение атрибута заключено в скобки {}, компилятор-анализатор XAMLобрабатывает его как расширение разметки, а не как строковый литерал.

Например, рассмотрим следующий элемент Rectangle, у которого свойству Background присвоено значение null.

<Rectangle Fill="{x:Null}" Stroke="Black" StrokeThickness="2" Height="20"/>

Поскольку компилятор-анализатор видит строку, заключенную в скобки {}, он знает, что это расширение разметки. Это всего лишь простенький трюк, хорошо известный анализатору XAML. Расширения разметки в XAML объявляются так же, как и классы. Для этого используется синтаксис элемента свойства.

Синтаксис элемента свойства. Синтаксис элемента свойства позволяет превратить любое свойство в полноценный элемент дерева XAML, в который можно добавлять дочерние элементы. Это станет очевиднее из примера.

Представим, что расширение разметки можно объявлять следующим образом:

<Binding RelativeSource="{RelativeSource modeEnumValue}" .../>

Или, возможно, таким:

<object mode="{Binding RelativeSource={RelativeSource modeEnumValue} ...}" .../>

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

<Binding>

 <Binding.RelativeSource>

   <RelativeSource Mode="modeEnumValue"/>

 </Binding.RelativeSource>

</Binding>

//иболеесложныйпример

<Binding>

 <Binding.RelativeSource>

   <RelativeSource

     Mode="FindAncestor"

     AncestorType="{x:Type typeName}"

     AncestorLevel="2"

   />

 </Binding.RelativeSource>

</Binding>

Объявлять все эти объекты нужно таким образом можно потому, что они всего лишь классы. Скобки {}, по сути, служат синтаксической оболочкой того, что скрыто за кулисами, то есть за кулисами создается вся масса классов (как только что было продемонстрировано). Такой синтаксис элемента свойства можно применять ко всему. В примере ниже другое свойство используется в качестве элемента для свойства Background типа Button.

<Button Width="auto" Content="Button">

   <Button.Background>

       <SolidColorBrush Color="Blue"/>

   </Button.Background>

</Button>

Посколькукласс System.Windows.Markup.MarkupExtension базовый, отнегонаследуютсявсерасширенияразметки. Вот список стандартных классов расширений разметки:

  • System.Windows.Markup.ArrayExtension

  • System.Windows.Markup.NullExtension

  • System.Windows.Markup.StaticExtension

  • System.Windows.Markup.TypeExtension

  • System.Windows.ResourceKey

  • System.Windows.DynamicResourceExtension

  • System.Windows.ColorConvertedBitmapExtension

  • System.Windows.StaticResourceExtension

  • System.Windows.TemplateBindingExtension

  • System.Windows.ThemeDictionaryExtension

  • System.Windows.Data.BindingBase

  • System.Windows.Data.RelativeSource

Чаще всего при программировании на платформе WPF используются расширения разметки, которые поддерживают ссылки на ресурсы (StaticResourceи DynamicResource) и привязки данных (Binding). Обратите внимание на отсутствие суффикса Extension. Он неявно подразумевается компилятором, поскольку скобки {} указывают на то, что суффикс Extension в расширении разметки НЕ требуется.

Расширение разметки StaticResource предоставляет значение свойства XAML путем замены на значение уже определенного ресурса. Дополнительные сведения см. в разделе «Расширение разметки StaticResource».

Расширение разметки DynamicResource предоставляет значение свойства XAML во время выполнения по ссылке на ресурс. Динамическая ссылка на ресурс приводит к новому поиску значения при каждом обращении к ресурсу.

Расширение разметки Binding предоставляет значение свойства, привязанное к данным, в соответствии с контекстом данных, применяемым для данного элемента. Это расширение разметки относительно сложное, в нем используется встроенный синтаксис для задания привязки данных. Дополнительные сведения см. в разделе «Расширение разметки Binding».

Расширение разметки RelativeSource предоставляет исходную информацию для привязки, которая может использоваться для перехода к нескольким возможным отношениям в дереве элементов во время выполнения. Это расширение предоставляет специальную исходную информацию для привязок, создаваемых в многократно используемых шаблонах и в коде в отсутствие полного знания о дереве элементов. Дополнительные сведения см. в разделе «Расширение разметки RelativeSource».

Существует еще несколько других расширений разметки, которые не относятся конкретно к использованию XAML в приложении WPF, а, скорее, являются частью спецификации и пространства имен самого языка XAML. Обычно их можно опознать по префиксу x:. Для их реализации в WPF используется тот же самый базовый класс MarkupExtension.

Расширение разметки x:Type предоставляет объект Typeдля именованного типа. Чаще всего оно используется в стилях и шаблонах. Дополнительные сведения см. в разделе «Расширение разметки x:Type».

Расширение разметки x:Static создает статические значения из сущностей кода типа значения, которые непосредственно не принадлежат к типу значения свойства, но могут быть приведены к нему.

Расширение разметки x:Null присваивает свойству XAMLзначение null.

Расширение разметки x:Array поддерживает создание общих массивов в синтаксисе XAML, когда поддержка коллекций, предоставляемая базовыми элементами и моделями элементов управления, намеренно не используется.

Что такое ресурсы и чем они полезны. Ресурсы — это многократно используемые объекты, которые можно объявлять в различных местах.

  • В приложении в файле App.xaml (или как у вас называется файл приложения). В этом случае у объявленного ресурса будет глобальная область действия приложения.

  • В свойстве Resources текущего объекта Window (при условии работы с объектом Window). В этом случае у объявленного ресурса будет область уровня объекта Window. У всех элементов интерфейса пользователя в объекте Window, где объявлен ресурс, будет доступ к объявленному ресурсу.

  • В свойстве Resources любого элемента FrameworkElement или FrameworkContentElement.

  • В отдельном файле ресурсов XAML.

Ресурс можно представить как один объект, сохраненный в словаре объектов ресурсов. И поэтому у каждого ресурса ДОЛЖЕН быть ключ для безопасного извлечения уникального ресурса из словаря ResourceDictionary.

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

Каждый элемент уровня платформы (FrameworkElement или FrameworkContentElement) обладает свойством Resources, содержащим ресурсы (в виде словаря ResourceDictionary). Определять ресурсы можно для любого элемента. Однако чаще всего ресурсы определяются для корневого элемента — обычно это элемент Window.

После объявления ресурса его можно использовать в элементе. Например, в следующем коде XAML объявляется новый ресурс SolidColorBrush в элементе Window. Затем этот ресурс используется в качестве фона для двух объектов Button в элементе Window.

<Window x:Class="WPF_Tour_Beginners_Part_2.Window1"

   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

   xmlns:SeperateWPFUserControlDll="clr-namespace:SeperateWPFUserControl_Dll;assembly=SeperateWPFUserControl_Dll"

   xmlns:local="clr-namespace:WPF_Tour_Beginners_Part_2;assembly="

   xmlns:collections="clr-namespace:System.Collections;assembly=mscorlib"

   xmlns:sys="clr-namespace:System;assembly=mscorlib"

   Title="Window1" Height="300" Width="600"

   WindowStartupLocation="CenterScreen">

   <Window.Resources>

       <SolidColorBrush x:Key="windowLevelResourceBlueBrush" Color="Blue"/>

   </Window.Resources>

   <StackPanel x:Name="sp1" Orientation="Vertical">

       <!--Объявлениедвухобъектов Button, использующихресурсWindow.windowLevelResourceBlueBrush -->

       <Button Width="auto" Content="1st Button : I use the resourceBrushBlue Window Resource"

       Background="{StaticResource windowLevelResourceBlueBrush}"/>

       <Button Width="auto" Content="2nd Button : I use the resourceBrushBlue Window Resource"

       Background="{StaticResource windowLevelResourceBlueBrush}"/>

   </StackPanel>

</Window>

В этом простом примере использования ресурсов для двух объектов Button в качестве фона будут использоваться синие объекты SolidColorBrush. (Примечание. Мы ничего не сказали о том, как будет выглядеть кнопка при наведении на нее указателя мыши. Синий объект SolidColorBrush применяется в качестве фона, только когда указатель мыши не наведен на кнопку. Этот вопрос мы рассмотрим в статье, посвященной стилям и шаблонам.)

Еще следует отметить, что фактически мы используем расширение разметки StaticResourceExtension (помните, что суффикс Extension можно пропустить). Обращаться к ресурсу можно как к статическому или динамическому. Для этого используется расширение разметки StaticResourceExtension или DynamicResourceExtension соответственно.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]