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

Элементы управления Silverlight: расширенные элементы управления

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

В лекц. 7, "Элементы управления Silverlight: представления и компоновки", был представлен набор элементов управления Silverlight и проведен обзор таких основных элементов управления, как TextBox и CheckBox. Однако для современных насыщенных интерактивных приложений (RIAs) необходимы намного более сложные элементы управления, такие как таблицы с данными, календари и т.д. В данной лекции вы научитесь использовать эти элементы управления в своих Silverlight приложениях. Некоторые из этих элементов управления, такие как DataGrid (Таблица с данными), заслуживают отдельного рассмотрения, поэтому не ожидайте получить здесь полный API этих элементов управления. Однако в данной лекции предоставлено достаточно сведений об этих расширенных элементах управления, которые позволят понимать, что происходит при их использовании. Располагая этими знаниями, можно продолжать экспериментировать и изучать эти элементы управления уже самостоятельно.

Элемент управления DataGrid

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

При добавлении элемента управления DataGrid в окно редактирования XAML, получаем такой XAML-код:

<UserControl xmlns:my="clr-namespace:System.Windows.Controls;
                       assembly=System.Windows.Controls.Data"
             x:Class="SilverlightApplication1.Page" 
             xmlns=" http://schemas.microsoft.com/client/2007"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             Width="400" Height="300">
  <Grid x:Name="LayoutRoot" Background = "White">
    <my:DataGrid>
    </my:DataGrid>
  </Grid>
</UserControl>

Пока что DataGrid не может делать практически ничего, поэтому добавим в него два свойства: имя и AutoGenerateColumns (Столбцы формируются автоматически), которое обеспечит автоматическое создание необходимых столбцов данных при привязке сетки к DataGrid. Вот как выглядит XAML для Data-Grid после этих дополнений:

<my:DataGrid x:Name="GrdHeadline" AutoGenerateColumns="True"> 
</my:DataGrid>

ВОТ И все, что требуется для подготовки DataGrid к использованию связанных данных. Прежде чем переходить к остальным свойствам, методам и событиям этого элемента управления, давайте выполним простую привязку данных. Будем использовать RSS-канал по адресу http://feeds.reuters.com/reuters/oddlyEnoughNews?format=xml .

Итак, в начале Page.xaml.cs добавляем ссылку на System.Net:

using System.Net;

Далее необходимо настроить объект WebClient (Веб-клиент) на чтение данных по этому URI и добавить обработчик события для обработки завершения загрузки данных. Для этого в конструктор Page добавляем следующий код:

WebClient client = new WebClient(); 
Uri uri = new Uri("http://feeds.reuters.com/reuters/topNews?format=xml"); 
client.DownloadStringCompleted + = 
      new DownloadStringCompletedEventHandler( client DownloadStringCompleted); 
client.DownloadStringAsync(uri);

Теперь по завершении загрузки данных будет запускаться обработчик события

client DownloadStringCompleted. В этой функции будет использоваться специальный класс типа NewsHeadline (Заголовок новостей). Вот код этого класса:

public class NewsHeadLine 
{
  public string strHead { get; set; }
  public string strLine { get; set; } 
}

client DownloadStringCompleted использует библиотеки System.Xml.Linq, поэтому понадобится добавить ссылку на них. Для этого щелкните правой кнопкой мыши References и выберите Add Reference. На вкладке .NET вы увидите библиотеку System.Xml.Linq, как показано на рис. 8.1. Выберите ее и щелкните OK.

Чтобы код скомпилировался, в нем должна быть указана эта библиотека. Для этого просто добавляем данное выражение в начало Page.xaml.cs:

using System.Xml.Linq;

Итак, получаем код обработчика событий client DownloadStringCompleted:

void client DownloadStringCompleted(
object sender, DownloadStringCompletedEventArgs e) 
{ 
  XDocument xmlHeadlines = XDocument.Parse(e.Result); 
  var headlines = from story in xmlHeadlines.Descendants("item") 
                   select new NewsHeadLine { 
                      strHead = (string)story.Element("title"), 
                      strLine = (string)story.Element("link") }; 
                      GrdHeadline.ItemsSource = headlines; 
                     }

Этот код обеспечивает синтаксический разбор данных, возвращаемых в результате запроса к сервису (хранящихся в e.Result), в объект XDocument. После этого с помощью Linq данные выбираются из XDocument и создается коллекция заголовков. Затем эта коллекция присваивается как значение свойству ItemsSource (Источник элементов) элемента управления DataGrid. Результаты представлены на рис. 8.2.

(рис 8.1) Добавление ссылки на System.Xml.Linq(рис 8.2) Образец коллекции заголовков, созданный при выполнении элемента управления DataGrid

В DataGrid возможны два режима выбора: одиночный, при котором можно выбирать по одной строке, и множественный, при котором при удержании клавиш Ctrl и/или Shift может быть выбрано несколько строк.

Эти режимы задаются с помощью свойства SelectionMode (Режим выбора), которое принимает значения DataGridSelectionMode.Single для одиночного выбора и DataGridSelectionMode.Extended для множественного.

При использовании единичного режима выбранный элемент сохраняется в SelectedItem. Если этот объект типа object, перед использованием он должен быть приведен к соответствующему типу. Вы видели, что сетка заполнялась элементами определенного нами класса NewsHeadLine.

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

NewsHeadLine theHeadline = GrdHeadline.SelectedItem as NewsHeadLine;

Когда установлен режим множественного выбора, можно использовать свойство SelectedItems, возвращающее коллекцию списков. Это очень просто сделать, вот код:

string strHead;
string strLink;
System.Collections.IList listOfItems = GrdHeadline.SelectedItems;
foreach(NewsHeadLine newsHead in listOfItems)
{
strHead = newsHead.strHead;
strLink = newsHead.strLine; }

В данном случае, свойство SelectedItems возвращает System.Collections.IList. После этого можно перебрать его элементы, извлекая каждый из объектов NewsHeadline и получая его данные.

При использовании любой таблицы, и DataGrid здесь не исключение, всегда полезно сделать ее более удобной для восприятия путем использования цветных полос, т.е. чередовать закрашенную и незакрашенную строки попеременно разными цветами или оттенками. В данном случае, чтобы сделать DataGrid полосатым, можно использовать свойства RowBackground (Фон строки) и AlternatingRowBack-ground (Чередующийся фон строки). В качестве значений этим свойствам задается цвет кисти следующим образом:

GrdHeadline. RowBackground =
new SolidColorBrush(Colors.LightGray); GrdHeadline.Alternating RowBackground = new SolidColorBrush (Colors. Yellow);

Результат такого форматирования можно увидеть на рис. 8.3.

(рис 8.3) Чередование цветов строк

Возможно, вы обратили внимание, что столбцы добавляются в том порядке, в котором данные определены в классе NewsHeadLine. Однако порядок вывода данных на экран можно менять. Настройку по умолчанию можно переопределить свойством DisplayIndex (Индекс отображения). Например, в нашем DataGrid два столбца. В первом выводятся заголовки, во втором - ссылки. Их можно поменять местами следующим способом:

GrdHeadline.Columns[0]. DisplayIndex = 1; GrdHeadline.Columns[1].DisplayIndex = 0;

Более широкие возможности управления визуальным представлением данных в сетке предоставляет шаблон данных. Шаблон данных-это XAML, определяющий то, как должны быть организованы данные, включая привязку к конкретным полям. Например, в предыдущих примерах вывода каждая ячейка таблицы была связана с определенным элементом RSS-канала. Чтобы вывести два поля RSS-канала в одной ячейке, необходимо использовать шаблон данных. Рассмотрим следующий XAML:

<UserControl xmlns:my="clr-namespace:System.Windows.Controls;
                       assembly=System.Windows.Controls.Data" 
             x:Class="DataGrid.Page" xmlns=" http://schemas.microsoft.com/client/2007"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xa ml"
             Width="400" Height="300">
  <Grid x:Name="LayoutRoot" Background = "White">
    <my:DataGrid x:Name="GrdHeadline" AutoGenerateColumns="True">
      <my:DataGrid.Columns>
        <my:DataGridTemplateColumn>
          <my:DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
              <StackPanel Orientation = "Vertical">
                <TextBlock Text="123"></TextBlock>
                <TextBlock Text="{Binding strHead}"></TextBlock>
                <TextBlock Text="{Binding strPubDate}"></TextBlock>
              </StackPanel>
            </DataTemplate>
          </my:DataGridTemplateColumn.CellTemplate>
        </my:DataGridTemplateColumn>
        <my:DataGridTemplateColumn>
          <my:DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
              <TextBlock Text="{Binding strLine}"></TextBlock>
            </DataTemplate>
          </my:DataGridTemplateColumn.CellTemplate>
        </my:DataGridTemplateColumn>
      </my:DataGrid.Columns>
    </my:DataGrid>
  </Grid>
</UserControl>

В этом XAML столбцы DataGrid заданы заранее с помощью элемента <my:DataGrid.Columns>. Мы можем переопределить шаблон для столбцов по умолчанию, когда в ячейке выводится одно поле, задавая для каждой ячейки <my:DataGridTemplateColumn.CellTemplate>, в котором имеется код, описывающий, как должна отображаться ячейка.

Как видите, описано только две ячейки, поэтому данная таблица, независимо от количества полей данных, будет иметь только два столбца. Первый столбец, определенный шаблоном первой ячейки, будет представлен элементом StackPanel, содержащим три текстовых поля, в которых выводятся заданное в коде "123", связанное с данными свойство strHead класса NewsHeadline и связанное с данными свойство strPubDate того же класса NewsHeadline. StackPanel выводит эти поля друг над другом.

Второй столбец, описанный шаблоном второй ячейки, является простым TextBlock, связанным с полем strLine. Возможно, вы заметили, что здесь появилось еще одно поле, strPubDate, которого не было в исходном примере класса, поэтому описание класса и код привязки необходимо обновить. Вот новое описание класса:

public class NewsHeadLine 
{
  public string strHead { get; set; }
  public string strLine { get; set; }
  public string strDescription { get; set; }
  public string strPubDate { get; set; } 
}

И вот новый код привязки данных, который обеспечивает привязку дополнительных полей:

void client DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{ 
  XDocument xmlHeadlines = XDocument.Parse(e.Result); 
  var headlines = from story in xmlHeadlines.Descendants("item") 
                select new NewsHeadLine { 
                    strHead = (string)story.Element("title"), 
                    strLine = (string)story.Element("link"), 
                    strDescription = (string)story.Element("description"), 
                    strPubDate = (string)story.Element("pubDate") 
                   };
  GrdHeadline.ItemsSource = headlines; 
}

Чтобы увидеть новые данные, необходимо внести еще одну небольшую коррективу- изменить высоту строки. Сейчас в ней может отображаться только одна строка текста, в результате чего содержимое первой ячейки будет обрезано по вертикали. Также понадобиться отключить автоматическое определение столбцов, потому что мы хотим переопределить поведение привязки данных DataGrid по умолчанию. Это обеспечивает следующий код (поместите его в конструктор Page ):

GrdHeadline.AutoGenerateColumns = false; 
GrdHeadline.RowHeight = 60;

Теперь, после выполнения этого кода, на экран будет выведен DataGrid с ячейками, соответствующими заданным шаблонам (рис. 8.4). Выглядит не очень красиво, но замечательно иллюстрирует возможности управления представлением данных в элементе управления DataGrid.

(рис 8.4) Использование шаблона данных для определения визуального представления данных

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

Элементы управления Calendar и DatePicker

Возможность использования дат в приложениях Silverlight обеспечивается элементами управления Calendar (Календарь) и DatePicker (Элемент выбора дат). Элемент управления Calendar выводит на экран дни заданного месяца или месяцы заданного года и предоставляет кнопки со стрелками для перемещения по месяцам или годам. DatePicker сочетает это представление с текстовым полем, в которое пользователь может вводить дату в соответствующем формате, или выпадающим списком, в котором можно выбрать определенную дату.

Рассмотрим сначала элемент управления Calendar. Он прост, поэтому удобно начинать с него:

<UserControl xmlns:my="clr-namespace:System.Windows.Controls; assembly=System.Windows.Controls" 
             x:Class="cal.Page" 
             xmlns=" http://schemas.microsoft.com/client/2007" 
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             Width = "400" Height="300">
  <Grid x:Name="LayoutRoot" Background="White">
    <my:Calendar x:Name="cal"></my:Calendar>
  </Grid>
</UserControl>

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

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

Месяц отображаемой даты задается свойством DisplayDate (Отображаемая дата). Например, следующий код обеспечивает выбор даты 1 января 2009 года:

DateTime d = new DateTime(2009, 1, 1); 
cal.DisplayDate = d;

Это обеспечит отображение выбранного месяца, но без указания конкретного дня. Посмотрите на календарь, представленный на рис. 8.6.

(рис 8.6) Изменение отображаемой даты

Сравните рис. 8.6 и рис. 8.5. Можно заметить, что на рис. 8.6 дата не выбрана. При задании отображаемой даты выбранная дата была обнулена, поэтому свойство SelectedDate (Выбранная дата) имеет значение null. Если вы выберете какой-то день на экране, свойству SelectedDate будет присвоено это значение (типа DateTime ), или дату можно задать в коде через все то же свойство SelectedDate. Например:

DateTime s = new DateTime(2009, 1, 31); cal.SelectedDate = s;

Как это выглядит, можно увидеть на рис. 8.7. Теперь на отображаемом календаре выбрана дата, 31 января.

Коллекция BlackoutDates (Недоступные даты) позволяет задавать диапазон дат, которые не могут быть выбраны. Эта коллекция содержит тип CalendarDateRangeCollection (Коллекция диапазона дат календаря), в который могут добавляться диапазоны дат. Все даты, попадающие в этот диапазон, будут отображаться неактивными и, таким образом, не могут быть выбраны. Свойства SelectableDateStart (Начало дат, доступных для выбора) и SelectableDateEnd (Конец дат, доступных для выбора) задают диапазон отображаемых дат. Например, с помощью этих свойств можно обеспечить вывод на экран календарь, содержащий диапазон отображаемых дат и диапазон (обычно поддиапазон) дат, доступных для выбора.

(рис 8.7) Использование свойства SelectedDate

Элемент управления DatePicker сочетает эту функциональность с текстовым полем. Свойство Text этого поля содержит все, что пользователь вводит в качестве даты. Если невозможно выполнить синтаксический разбор введенных пользователем данных, формируется ошибка TextParseError (Ошибка синтаксического разбора текста).

Справа от текстового поля можно увидеть значок, выбор которого обеспечивает отображение элемента управления Calendar для выбора даты. Когда пользователь щелкает этот значок, формируется событие CalendarOpened (Календарь открыт). Когда пользователь закрывает его, формируется событие CalendarClosed (Календарь закрыт). Элементы управления Calendar и DatePicker обеспечивают базовые средства для создания приложений, в которых ввод основывается на датах и которые могут отображать информацию календаря.

Элементы управления RepeatButton и ToggleButton

Элемент управления RepeatButton (Кнопка повтора) предоставляет кнопку, при нажатии которой формируется множество событий щелчка. Частота формирования событий определяется свойством Delay (Задержка), оно задается в миллисекундах. Например, рассмотрим следующий XAML:

<RepeatButton x:Name="rpt" Delay="100"
Content="0" Click="rptClick"> </RepeatButton>

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

private void rpt Click(object sender, RoutedEventArgs e) 
{
  int n = Convert.ToInt16(rpt.Content);
  n++ ;
  rpt.Content = n.ToString(); 
}

Когда пользователь щелкает кнопку, текущее значение свойства Content извлекается, преобразовывается в целое число, увеличивается на единицу и опять присваивается как значение свойства Content. В результате надпись на кнопке увеличивается, пока пользователь удерживает кнопку мыши нажатой над RepeatButton. Это может использоваться как способ контроля при обработке множества повторяющихся действий. Например, для различных типов счетчиков, реализованных таким образом, что пользователю предоставляется кнопка со стрелкой, и, пока он удерживает ее, значение увеличивается.

Во всех остальных отношениях, RepeatButton является обычной кнопкой, поэтому все детали о его использовании можно найти в лекц. 7, в которой рассматривается универсальный элемент управления Button.

ToggleButton (Выключатель) - это кнопка, которая, будучи нажатой, остается в этом состоянии до тех пор, пока по ней не щелкнут снова. Этот элемент управления сочетает в себе переключатель и обычную кнопку. Свойства элемента управления ToggleButton подобны используемым в переключателях и обычных кнопках: ToggleButton тоже имеет свойство IsChecked, с помощью которого можно извлекать его текущее значение, и свойство IsThreeState, которое посредством значения Null позволяет задавать третье состояние, среднее между обычным и нажатым.

Как и стандартный элемент управления Button (лекц. 7), RepeatButton и ToggleButton являются элементами управления с содержимым, т.е. могут использоваться для отображения сложного содержимого и создания кнопок с изображениями, видеокнопок и многого другого для ваших приложений Silverlight.

Элемент управления ScrollViewer

Элемент управления ScrollViewer является контейнером для отображения информации. Он предоставляет горизонтальную и вертикальную полосы прокрутки, что обеспечивает возможность пользователю перемещать область отображения и просматривать все содержимое, если его размеры превышают размеры контейнера. Наличие полос прокрутки определяется свойствами HorizontalScrollBarVisibility (Видимость горизонтальной полосы прокрутки) и VerticalScrollBarVisibility (Видимость вертикальной полосы прокрутки). По умолчанию, если содержимое превышает размеры ScrollViewer, отображается вертикальная полоса прокрутки; горизонтальная полоса прокрутки не отображается независимо от содержимого. Рассмотрим следующий пример XAML:

<UserControl x:Class="sviewer.Page"
  xmlns="http://schemas.microsoft.com/client/2007" 
  xmlns:x=" http://schemas.microsoft.com/winfx/2006/xaml" 
  Width = "400" Height="300">
  <Grid x:Name="LayoutRoot" Background ="White">
    <ScrollViewer>
      <Image Source="mix08  1280.jpg" Stretch="None" />
    </ScrollViewer>
  </Grid>
</UserControl>

В данном случае ScrollViewer является единственным дочерним элементом управления на рабочей поверхности размером 400 * 300, поэтому его размеры также будут 400 * 300. В нем располагается изображение размером 1280 * 1024. Результат можно увидеть на рис. 8.8.

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

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

Но если в описание ScrollViewer в XAML добавить HorizontalScrollBarVisibility="True", пользователь сможет увидеть все остальное изображение. Вот этот XAML-код:

<ScrollViewer HorizontalScrollBarVisibility="Visible">
  <Image Source="mix08  1280.jpg" Stretch="None" /> 
</ScrollViewer>

Результаты представлены на рис. 8.9.

(рис 8.9) Использование ScrollViewer с горизонтальной полосой прокруткиПодсказка Можно также переопределить видимость вертикальной полосы прокрутки. По умолчанию она видимая, но ее можно отключить (т.е. она не будет отображаться), задав свойству VerticalScrollBarVisibility значение Hidden.

Элемент управления Slider

Элемент управления Slider обеспечивает пользователю возможность выбирать значение из заданного диапазона, передвигая вертикальный элемент (называемый бегунком (thumb)) вдоль линии, начиная от наименьшего значения в диапазоне, заканчивая наибольшим значением. Доступ к значению обеспечивается через свойство Value (Значение), возвращающее величину типа Double.

Элемент управления Slider можно настроить множеством способов. Например, свойства Minimum (Минимум) и Maximum (Максимум) используются для определения минимального и максимального значений диапазона. Если необходимо, чтобы пользователь выбирал значение из диапазона чисел от О до 100, задайте свойству Minimum значение 0 и свойству Maximum значение 100.

Еще одно свойство, связанное с элементом управления Slider, - Orientation (Ориентация), которое используется для определения направления перемещения бегунка. Ему может быть заданы значения Horizontal (Горизонтально) или Vertical (Вертикально).

Когда свойству Orientation задано значение Horizontal, по умолчанию перемещение Slider от наименьшего к наибольшему значению реализуется в направлении слева направо, и снизу вверх, если Orientation задано значение Vertical. Эти стандартные настройки можно переопределить свойством IsDirectio-nReversed (Обратное направление), задание значения True которому обеспечит изменение направления возрастания значений в Slider.

Кроме того, можно перемещать бегунок, щелкая на полосе перемещения типового элемента управления Slider. Каждый щелчок обеспечивает изменение значения на определенную величину. Это поведение определяется свойством LargeChange (Быстрое перемещение), задание числового значения, которому обеспечивает увеличение или уменьшение значения бегунка на заданную величину.

Далее приведен пример элемента управления Slider в XAML:

<Slider x:Name="sldr" Maximum="100"
      Orientation = "Vertical"
      IsDirection Reversed = "True"
      LargeChange="10">
</Slider>

Создаваемый здесь Slider будет вертикальным с наименьшим значением сверху, наибольшим - снизу. Он обеспечит возможность, перетягивая бегунок, выбирать значения в диапазоне от 0 до 100. Также пользователь сможет увеличивать значения на 10, щелкая полосу перемещения.

Заключение

В данной лекции мы продолжили изучение набора элементов управления Silverlight. Много внимания было уделено DataGrid, его свойствам, методам и событиям, поскольку это важный элемент управления, обеспечивающий приложениям функциональность, аналогичную электронным таблицам. При обсуждении DataGrid представлен код, предлагаемый Silverlight для упрощения привязки данных, а также рассмотрены шаблоны данных и их использование для компоновки таблиц. Кроме того, вы познакомились с другими расширенными инструментами, доступными в Silverlight, включая элементы управления Calendar, DatePicker, ScrollViewer и Slider.

На этом мы завершаем обзор элементов управления Silverlight и в следующей лекции займемся созданием собственных элементов управления.

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