Введение в Microsoft Silverlight 2

Создание собственного элемента управления Silverlight

Показывать лекцию целиком

В лекц. 7, "Элементы управления Silverlight: представления и компоновки", был представлен краткий обзор использования Microsoft Visual Studio для создания приложений Silverlight на C#. В лекц. 8, "Элементы управления Silverlight: расширенные элементы управления", описаны некоторые элементы управления, доступные в Silverlight. Вероятно, на данный момент, вас интересует, какие еще элементы управления доступны в базовом наборе. Но есть два варианта: элементы управления можно либо покупать, либо создавать самостоятельно. Есть множество производителей элементов управления; подробнее о них можно узнать на сайте http://www.silverlight.net. Однако, используя Silverlight, можно создавать собственные элементы управления для Silverlight. В данной лекции предлагается практический подход к построению таких элементов управления.

Создание проекта

Итак, начнем. Первый шаг - создание нового проекта Silverlight в Visual Studio. Делаем это, выбирая опцию New Project в меню File (рис. 9.1).

(рис 9.1) Создание проекта нового элемента управления

Как видно на рис. 9.1, этот проект будет называться CircleControl (Элемент управления круг). Если вернуться к лекц. 4, "Основы XAML", вы увидите, что XAML не предлагает фигуры Circle (Круг), но в нем есть Ellipse со свойствами, определяющими ширину и высоту. Мы унаследуем фигуру от Ellipse, но вместо ширины и высоты применим свойство Radius (Радиус), что позволит Silverlight отрисовывать круг.

Щелкните OK, и откроется Мастер приложений Silverlight (рис. 9.2). Примите настройки по умолчанию, и Visual Studio создаст все необходимое для приложения Silverlight. Подробнее о приложениях Silverlight и каждом из составляющих их файлов рассказывается в лекц. 3, "Использование Visual Studio с Silverlight 2". Теперь все готово для следующего шага - добавления самого элемента управления.

(рис 9.2) Мастер приложений Silverlight Application Wizard

Добавление шаблона элемента управления

Элемент управления Silverlight создается точно также, как любой другой проект: с использованием XAML и, если необходимо, некоторого выделенного кода. Применяемый шаблон обеспечивает создание тестового проекта, который включает файл App.xaml для кода приложения и файл Page.xaml основного UI. Создаваемый элемент управления будет добавлен в Page.xaml. Совсем скоро вы увидите, как это делается.

Сначала создадим сам элемент управления. Щелкнем правой кнопкой мыши на проекте (в данном случае, CircleControl), выберем Add и затем New Item (Новый элемент). Появится диалоговое окно Add New Item (Добавление нового элемента), как показано на рис. 9.3.

(рис 9.3) Добавление нового элемента управления Silverlight

В этом диалоговом окне из предлагаемых категорий выбираем Silverlight, выбираем шаблон Silverlight User Control и присваиваем ему имя. После этого щелкаем Add.

Будет создан базовый UserControl. Вот как выглядит XAML для элемента управления Circle в проекте CircleControl:

<UserControl x:Class="CircleControl.Circle"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     Width="400"Height="300">
  <Grid x:Name="LayoutRoot" Background="White">
  </Grid>
</UserControl>

Обратите внимание на использование пространств имен. Для x:Class, который определяет объект для Silverlight, задано значение CircleControl.Circle. Поскольку круг будет иметь только один визуальный элемент, унаследованный от базового типа Ellipse, в сетку LayoutRoot необходимо добавить следующее:

<Grid x:Name="LayoutRoot" Background="White">
  <Ellipse x:Name="BaseEllipse">
  </Ellipse> 
</Grid>

Написание кода элемента управления

Код элемента управления очень прост. Circle - это UserControl, формирующий визуальное представление заданного XAML, который содержит Ellipse. К этому требуется добавить свойство Radius, определяющее радиус Circle, и свойство FillColor (Цвет заливки), обеспечивающее возможность закрашивать круг. UserControl не предоставляет свойство Fill, поэтому его придется реализовать самостоятельно.

Вот этот код. Он должен находиться в файле выделенного кода с расширением .cs, поэтому если элемент управления назван Circle.xaml, этот файл будет называться Circle.xaml.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace CircleControl
{
  public partial class Circle : UserControl
  {
    public Circle()
    {
      // Необходимо для инициализации переменных 
      InitializeComponent();
    }
    public double Radius
    {
      get
      {
        return BaseEllipse.Width / 2;
      }
      set
      {
        BaseEllipse.Width = value * 2; 
        BaseEllipse.Height = value * 2;
      }
    }
    public SolidColorBrush Fill
    {
      get
      {
        return (SolidColorBrush)BaseEllipse.Fill;
      }
      set
      {
        BaseEllipse.Fill = (SolidColorBrush)value;
      }
    }
  }
}

Как видите, все очень просто. Свойство Radius типа double возвращает в методе get ширину BaseEllipse (Базовый эллипс), деленную на 2. Для типа Ellipse всегда задаются ширина и высота, и, естественно, радиус круга является половиной ширины или высоты фигуры.

Аналогично, задавая значение Radius, вы хотите, чтобы ширина и высота базового Ellipse были в два раза больше радиуса. Это выполняется в методе set свойства.

Чтобы определить свойство Fill, необходимо привести входящее значение к типу SolidColorBrush и задать его в качестве значения Fill. Чтобы возвратить значение Fill базового эллипса, приводим его к SolidColorBrush. Все очень просто!

Теперь, когда мы получили элемент управления, можно реализовать его в приложении. Если вспомнить лекц. 3, стандартный шаблон в качестве UI по умолчанию для приложения задает Page.xaml. Итак, добавим наш элемент управления туда.

Прежде всего, необходимо добавить ссылку на пространство имен нашего элемента управления. В данном случае, проект называется CircleControl, и его пространство имен имеет такое же имя. Точные сведения о пространстве имен можно найти в свойствах проекта. Для этого щелкните проект правой кнопкой мыши и выберите Properties, чтобы открыть диалог Project Properties. Это подробно обсуждалось в лекц. 3.

Ваше исходное объявление UserControl в Page.xaml должно выглядеть аналогично следующему фрагменту кода.

Примечание В некоторых версиях Visual Studio Tools для <UserControl> применяется <Grid>, в некоторых - <Canvas>. В данном случае для демонстрационных целей используется <Canvas>, но не будет никаких проблем, если вы возьмете <Grid>, потому что оба этих элемента управления являются контейнерами.
<UserControl x:Class="CircleControl.Page" 
   xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:circ="clr-namespace:CircleControl"
   Width="640" Height="480">
  <Canvas x:Name="LayoutRoot">
  </Canvas>
</UserControl>

Теперь, когда пространство имен объявлено, можно добавить ссылку на элемент управления. Заметьте, что для данного пространства имен префиксом XML объявлен circ, поэтому, когда вы начинаете вводить его в редакторе, функция IntelliSense предлагает этот тег. Это показано на рис. 9.4.

(рис 9.4) IntelliSense и пространства имен специальных элементов управления

Функция IntelliSense также обеспечит выбор имени элемента управления и доступных для него свойств (в данном случае, это все свойства пользовательского элемента управления плюс описанные ранее Fill и Radius ). На рис. 9.5 представлен выбор свойства Radius в IntelliSense.

(рис 9.5) IntelliSense и свойства специального элемента управления

Вот пример Page.xaml с объявлением пространства имен и описанием двух кругов:

<UserControl x:Class="CircleControl.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x=" http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:circ="clr-namespace:CircleControl"
    Width="640" Height="480">
  <Canvas x:Name="LayoutRoot">
    <circ:Circle Fill="Black" Radius="100"
                 Canvas.Left="0" Canvas.Top="50">      
    </circ:Circle>
    <circ:Circle Fill = "Red" Radius="50"
                 Canvas.Left="0" Canvas.Top="50">      
    </circ:Circle>
  </Canvas>
</UserControl>

Как это выглядит, можно увидеть на рис. 9.6.

(рис 9.6) Использование элемента управления Circle на странице

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

Создание библиотек классов Silverlight

Среди шаблонов Visual Studio для Silverlight 2 есть шаблон, позволяющий создавать библиотеку классов, которую можно без труда использовать в других проектах. Эта библиотека классов может включать элементы управления Silverlight. В данном разделе на простом примере создания элемента управления Square (Квадрат) будет продемонстрировано добавление элементов управления в библиотеку.

Прежде всего, откроем Visual Studio и выберем New Project в меню File. Появится диалоговое окно New Project. Создайте в нем новый проект библиотеки классов Silverlight и присвойте ему соответствующее имя. Пример этого можно увидеть на рис. 9.7.

(рис 9.7) Создание новой библиотеки классов Silverlight

При этом будет создан проект библиотеки классов, как показано на рис. 9.8. Это обычный проект библиотеки классов Visual Studio, поэтому если вы знакомы с разработкой на C#, ваши навыки пригодятся и в Silverlight 2.

Чтобы добавить новый элемент управления Silverlight, щелкните правой кнопкой мыши на проекте, выберите Add и затем выберите New Item, как делали это ранее (если необходимо освежить память, вернитесь к рис. 9.3), и назовите его SquareControl (Элемент управления квадрат).

Теперь можете редактировать XAML и код элемента управления, выполняя те же шаги, что и ранее. Вот пример XAML для элемента управления Square:

Примечание Некоторые версии Visual Studio Tools создают Grid вместо Canvas под именем LayoutRoot. В данном разделе используется Canvas, но он может быть без проблем заменен на Grid.
<UserControl x:Class="SquareLib.SquareControl"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x=" http://schemas.microsoft.com/winfx/2006/xaml"
   Width="640" Height="480">
  <Canvas x:Name="LayoutRoot" >
    <Rectangle x:Name="rootControl"></Rectangle>
  </Canvas>
</UserControl>
(рис 9.8) Проект библиотеки классов в Visual Studio

Аналогично представленному ранее элементу управления Circle, Square тоже создается на базе существующего элемента управления XAML В данном случае используется Rectangle, который мы назовем rootControl (Корневой элемент управления). Вот код на C#, реализующий элемент управления Square:

using System;
using System.Net;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace SquareLib {
    public partial class SquareControl:UserControl {
        public SquareControl() 
        {
            // Необходимо для инициализации переменных 
            InitializeComponent(); 
        }
        public double Size 
        { 
            get { return rootControl.Width; }
            set { rootControl.Width = value; 
                  rootControl.Height = value; 
                } 
        }
        public SolidColorBrush Fill 
        { 
            get { return (SolidColorBrush)rootControl.Fill; }
            set { rootControl.Fill = (SolidColorBrush)value; } 
        } 
    } 
}

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

Чтобы использовать эту библиотеку классов, необходимо просто создать новый проект и добавить в него ссылку на нее. Итак, создадим новый проект Silverlight. Для этого в диалоговом окне New Project (File, New Project) выберем шаблон Silverlight Project.

Стандартный шаблон создает решение с двумя проектами: элемент управления Silverlight и Веб-сайт ASP.NET для его размещения.

Проект Silverlight Control позволяет добавлять ссылку, щелкнув правой кнопкой мыши папку References и выбрав Add Reference (рис. 9.9).

(рис 9.9) Добавление ссылки на ваш проект Silverlight

Через открывшееся диалоговое окно можно перейти в каталог, в котором располагается DLL, скомпилированная из вашего проекта библиотеки классов. Она должна располагаться в подкаталоге ClientBin. Добавьте ссылку, и ее можно будет увидеть в списке ссылок. Если ваша библиотека классов имеет какие-либо зависимости, они также будут представлены в этом списке. На рис. 9.10 показана ссылка на сборку SquareLib, после ее удачной компиляции.

(рис 9.10) Использование вашей специальной ссылки

Теперь можно вернуться к Page.xaml и добавить ссылку на пространство имен, что позволит использовать элементы управления из этой сборки. В этом очень поможет функция IntelliSense Visual Studio. В начале файла XAML, где описываются пространства имен, добавьте новый атрибут xmlns и задайте для него префикс (например, sq, как показано на рис. 9.11). IntelliSense предоставит список доступных сборок или схем. Вам просто надо выбрать имя необходимой сборки. В данном случае, это SquareLib, поэтому выбирайте ее. Обратите внимание, что ваш список сборок может выглядеть иначе, чем представленный на рис. 9.11.

(рис 9.11) IntelliSense и пространства именXML

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

<UserControl x:Class="SquareCLHost.Page"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x=" http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:sq="clr-namespace:SquareLib;assembly=SquareLib"
     Width="640" Height="480">
  <Canvas x:Name="LayoutRoot">
  </Canvas>
</UserControl>

Поскольку для этого пространства определен префикс sq, добавлять элементы управления из него можно посредством IntelliSense, используя этот префикс.

Итак, например, если в рамках элемента LayoutRoot ввести символ < для открытия узла XML, в выпадающем списке среди предлагаемых опций вы увидите sq:. Если вставить его в код, вы получите список доступных классов, как показано на рис. 9.12.

(рис 9.12) IntelliSense для библиотеки классов специального элемента управления

Наконец, приведем пример XAML с несколькими экземплярами SquareControl:

<UserControl x:Class="SquareCLHost.Page"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x=" http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:sq="clr-namespace:SquareLib;assembly=SquareLib"
     Width="640" Height="480">
  <Canvas x:Name="LayoutRoot" >
    <sq:SquareControl Size="10" Canvas.Top="10" Canvas.Left="10" Fill="Red">      
    </sq:SquareControl>
    <sq:SquareControl Size="10" Canvas.Top="20" Canvas.Left="20" Fill="Green">      
    </sq:SquareControl>
    <sq:SquareControl Size="10" Canvas.Top="30" Canvas.Left="30" Fill="Yellow">      
    </sq:SquareControl>
    <sq:SquareControl Size="10" Canvas.Top="40" Canvas.Left="40" Fill="Blue">      
    </sq:SquareControl>
  </Canvas>
</UserControl>

Заключение

В данной лекции представлена гибкая модель расширяемости, предлагаемая Silverlight 2. Вы научились добавлять элементы управления в приложения и инкапсулировать функциональность в элемент управления для упрощения повторного использования. Также было показано, как с помощью шаблона библиотеки классов Silverlight можно создавать элементы управления, компилируемые в сборки .NET, на которые могут ссылаться и использовать другие проекты.

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

В лекц. 10, "Создание взаимодействующих с сервером приложений в Silverlight", мы перейдем к немного более сложным вопросам и рассмотрим, как в Silverlight 2 реализуется работа с сетью и связь.

Вернуться к учебному плану