Блог Сергея Байдачного

Мой блог о технологиях

Archive for the ‘SilverLight’ Category

Введение в Silverlight 5 (часть 5)

leave a comment »

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

Отладка при связывании с данными

Начнем наш обзор с отладки приложений. Современный отладчик в Visual Studio давно позволяет разработчику получать всю необходимую информацию, если речь идет о коде на C#, C++ или даже JavaScript. Но как только речь заходит о XAML, то тут механизмы отсутствуют. Казалось бы, зачем нужна отладка в XAML, если тут идет декларативное описание интерфейса приложения. Действительно, отладка в XAML не нужна, если речь не идет о связывании с данными. Небольшой кусок кода, связывающий наши данные и интерфейс, может вызвать массу проблем при отладке. Ведь причин для возникновения проблем при связывании может быть множество, это и отсутствие какого-либо свойства, и проблемы с преобразованием либо же несоответствие типа. Но если связывание с данными описывается в XAML, то механизма получить информацию о проблеме не было. В Silverlight 5 возможна отладка XAML кода, описывающего связывание элементов управления и данных.

Рассмотрим небольшой пример кода на XAML:

 

   1:  <UserControl x:Class="SilverlightApplication1.MainPage"
   2:      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   5:      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   6:      Loaded="UserControl_Loaded"
   7:      mc:Ignorable="d"
   8:      d:DesignHeight="300" d:DesignWidth="400">
   9:   
  10:      <Grid x:Name="LayoutRoot" Background="White">
  11:          <Grid.Resources>
  12:              <Style TargetType="TextBox">
  13:                  <Setter Property="Background" Value="AliceBlue"></Setter>
  14:                  <Setter Property="Width" Value="200"></Setter>
  15:                  <Setter Property="Margin" Value="5"></Setter>
  16:              </Style>
  17:              <Style TargetType="TextBlock">
  18:                  <Setter Property="Margin" Value="5"></Setter>
  19:              </Style>
  20:          </Grid.Resources>
  21:          <Grid.RowDefinitions>
  22:              <RowDefinition Height="Auto"></RowDefinition>
  23:              <RowDefinition Height="Auto"></RowDefinition>
  24:              <RowDefinition Height="Auto"></RowDefinition>
  25:          </Grid.RowDefinitions>
  26:          <Grid.ColumnDefinitions>
  27:              <ColumnDefinition Width="Auto"></ColumnDefinition>
  28:              <ColumnDefinition Width="Auto"></ColumnDefinition>
  29:          </Grid.ColumnDefinitions>
  30:          <TextBlock Text="First Name:" Grid.Column="0" Grid.Row="0"></TextBlock>
  31:          <TextBlock Text="First Name:" Grid.Column="0" Grid.Row="1"></TextBlock>
  32:          <TextBlock Text="First Name:" Grid.Column="0" Grid.Row="2"></TextBlock>
  33:          <TextBox Grid.Row="0" Grid.Column="1" Text="{Binding FisrtName}"></TextBox>
  34:          <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding LastName}"></TextBox>
  35:          <TextBox Grid.Row="2" Grid.Column="1" Text="{Binding Age}"></TextBox>
  36:      </Grid>
  37:  </UserControl>

 

В результате мы получим небольшую формочку, которая позволяет заполнить три поля. Код, необходимый для работы формы может выглядеть как-то так:

 

   1:  private void UserControl_Loaded(object sender, RoutedEventArgs e)
   2:  {
   3:      Person p = new Person();
   4:      p.FirstName = "Sergey";
   5:      p.LastName="Baydachnyy";
   6:      p.Age = 33;
   7:   
   8:      LayoutRoot.DataContext = p;
   9:  }

 

И класс Person:

 

   1:  public class Person
   2:  {
   3:      public string FirstName { get; set; }
   4:      public string LastName { get; set; }
   5:      public int Age { get; set; }
   6:  }

 

Запустив это приложение, можно убедиться, что первое поле не было заполнено данными. Чтобы понять причину ошибки, достаточно установить Breakpoint в XAML файле на строку, описывающую связывание в первом поле и запустить приложение в режиме отладки. Вот что можно увидеть в окне Locals:

 

image

 

Тут и информация об ошибке (я намеренно сделал ошибку в имени поля) и данные об объекте и т. д. То есть, сгенерированный объект BindingState четко позволяет выявить проблему и проверить правильность данных.

Улучшенная поддержка шаблона MVVM

Данная поддержка состоит в расширении перечислимого типа UpdateSourceTrigger значением PropertyChanged. Данное значение влияет на обновление источника данных, происходящее при обновлении цели (элемента, куда данные выгружаются). Ранее этот тип поддерживал лишь два значения, это LostFocus и Explicit. Иными словами, если Вы связываете данные с элементом управления TextBox, то в случае двунаправленного связывания, при изменении элемента TextBox, источник мог быть обновлен лишь при потере фокуса или явным образом. Значение PropertyChanged позволяет реагировать на любые изменения в текстовом поле «на лету». При этом нет необходимости обрабатывать нажатия клавиш и т .д. Вот пример кода:

 

   1:  <UserControl x:Class="SilverlightApplication1.MainPage"
   2:      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   5:      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   6:      Loaded="UserControl_Loaded"
   7:      mc:Ignorable="d"
   8:      d:DesignHeight="300" d:DesignWidth="400">
   9:   
  10:      <Grid x:Name="LayoutRoot" Background="White">
  11:          <Grid.Resources>
  12:              <Style TargetType="TextBox">
  13:                  <Setter Property="Background" Value="AliceBlue"></Setter>
  14:                  <Setter Property="Width" Value="200"></Setter>
  15:                  <Setter Property="Margin" Value="5"></Setter>
  16:              </Style>
  17:              <Style TargetType="TextBlock">
  18:                  <Setter Property="Margin" Value="5"></Setter>
  19:              </Style>
  20:          </Grid.Resources>
  21:          <Grid.RowDefinitions>
  22:              <RowDefinition Height="Auto"></RowDefinition>
  23:              <RowDefinition Height="Auto"></RowDefinition>
  24:          </Grid.RowDefinitions>
  25:          <Grid.ColumnDefinitions>
  26:              <ColumnDefinition Width="Auto"></ColumnDefinition>
  27:              <ColumnDefinition Width="Auto"></ColumnDefinition>
  28:          </Grid.ColumnDefinitions>
  29:   
  30:          <TextBlock Text="First Name:" Grid.Column="0" Grid.Row="0"></TextBlock>
  31:          <TextBox Grid.Row="0" Grid.Column="1" Text=
  32:            "{Binding FirstName, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">
  33:          </TextBox>
  34:          <TextBlock Text="Your First Name:" Grid.Column="0" Grid.Row="1"></TextBlock>
  35:          <TextBlock Text="{Binding FirstName}" Grid.Column="1" Grid.Row="1"></TextBlock>
  36:   
  37:      </Grid>
  38:  </UserControl>

 

Ну и код модифицированного класса (чтобы работало связывание в двух направлениях):

 

   1:  public class Person: INotifyPropertyChanged 
   2:  {
   3:      public string firstName;
   4:   
   5:      public string FirstName {
   6:          get { return firstName; }
   7:          set { 
   8:              firstName = value;
   9:              OnPropertyChanged(new PropertyChangedEventArgs("FirstName"));
  10:          } 
  11:      }
  12:   
  13:      public event PropertyChangedEventHandler PropertyChanged;
  14:   
  15:      public void OnPropertyChanged(PropertyChangedEventArgs e)
  16:      {
  17:          if (PropertyChanged != null)
  18:              PropertyChanged(this, e);
  19:      }
  20:   
  21:  }

 

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

Использование связывания в стилях

Наконец-то, свершилось! Теперь в стилях также можно применять связывание. Это упрощает «натягивание» уникальной оболочки для каждого пользователя, позволяя загружать стили динамически, а также предусматривать установку и модификацию характеристик интерфейса.

Вот кусочек кода из предыдущего примера:

 

   1:  <Grid.Resources >
   2:      <Style TargetType="TextBox">
   3:          <Setter Property="Background" Value="{Binding background}"></Setter>
   4:          <Setter Property="Width" Value="{Binding width}"></Setter>
   5:          <Setter Property="Margin" Value="{Binding margin}"></Setter>
   6:      </Style>
   7:      <Style TargetType="TextBlock">
   8:          <Setter Property="Margin" Value="{Binding margin}"></Setter>
   9:      </Style>
  10:  </Grid.Resources>

 

Кроме этого я создал простой класс и мысленно представил, что данные мы выгружаем с сервераJ

 

   1:  public class TextStyle
   2:  {
   3:      public string width { get; set; }
   4:      public string background { get; set; }
   5:      public string margin { get; set; }
   6:  }

 

И связывание:

 

   1:  LayoutRoot.DataContext = new TextStyle() 
   2:  { width = "200", background = "Blue", margin = "5" };

 

Работает…J

Неявные шаблоны

Сергей Лутай уже написал об этой теме, поэтому я не буду себя утруждать. Читаем тут: http://lutay.uneta.com.ua/post/2011/04/14/Silverlight-5-Implicit-DataTemplate.aspx.

И другие изменения

Для полноты статьи приведем еще несколько нововведений, которые сами по себе интересны, но не стоят отдельного раздела из-за своей прозрачности (понятностиJ).

Особое внимание стоит обратить на новое событие DataContextChanged, которое представлено в базовом классе FrameworkElement. Теперь элемент способен отреагировать на изменение источника данных.

Если связывание происходит с другими элементами в модели, то теперь можно использовать свойство RelativeSource совместно с FindAncestor. Это позволяет указать вместо имени элемента, его тип и уровень вложенности. В результате нужный элемент будет найден в реальном времени и выполнено связывание.

Последнее нововведение, это доступность интерфейса ICustomTypeProvider, описывающего метод GetCustomType. Данный интерфейс может быть полезен, когда Вы создаете объекты с динамически сгенерированными свойствами. В этом случае Вы генерируете и возвращаете объект типа Type, описывающий все свойства, которые Вы хотели бы использовать при связывании. Аналогичным образом можно поступить, когда Вы хотите скрыть некоторые свойства от элементов управления, генерирующих свою структуру автоматически. Например, DataGrid, генерирующий свои колонки автоматически.

Реклама

Written by Sergiy Baydachnyy

20.10.2011 at 15:31

Опубликовано в SilverLight

Tagged with

Введение в Silverlight 5 (часть 4)

leave a comment »

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

Работа с текстом

Silverlight 5 предлагает несколько интересных возможностей при работе с текстом.

Так, элементы управления Control, TextBlock и TextElement, имеют новое свойство CharacterSpacing. Это свойство позволяет установить расстояние между символами внутри текста.

Свойство LineHeight позволяет установить ширину строки (можно интерпретировать, как расстояние между строками) и определено в таких элементах как Block, TextBlock, TextBox и RichTextBox. Для элемента RichTextBox можно также задать стратегию с помощью свойства LineStackingStrategy. Ниже пример текста внутри элемента TextBlock с расстоянием между строками 30 и расстоянием между символами – 200:

 

image

 

Наконец, Silverlight 5 стал поддерживать два новых текстовых элемента, это RichTextBlock и RichTextBlockOverflow. Эти элементы аналогичны элементам RichTextBox и RichTextBoxOverflow, но позволяют отображать текст только на чтение.

Для тех, кто еще не познакомился с элементом RichTextBlockOverflow, рассмотрим небольшой пример:

 

   1:  <StackPanel x:Name="LayoutRoot" Background="White"
   2:     Orientation="Horizontal" VerticalAlignment="Top">
   3:     <RichTextBlock
   4:        Width="250" FontSize="16" OverflowContentTarget=
   5:        "{Binding ElementName=SecondBox}">
   6:        <Paragraph>
   7:           В лесу родилась елочка,
   8:        </Paragraph>
   9:        . . . . . . . . //повторить 20 разJ
  10:     </RichTextBlock>
  11:   
  12:     <RichTextBlockOverflow Width="250" Name="SecondBox">
  13:     </RichTextBlockOverflow>
  14:  </StackPanel>

 

Результат работы этого кода показан ниже:

 

image

 

Как видно, RichTextBlockOverflow может отображать текст, который не «вмещается» в основной элемент RichTextBlock. Благодаря таким элементам мы можем азмещать текст в 2, 3 и более колонках (или реализовывать более сложные сценарии).

Печать

Silverlight 5 позволяет теперь не только реализовать растровую, но и векторную печать. Для этих целей используется все тот же метод Print класса PrintDocument, который осуществляет попытку печати в векторном формате, а в случае неудачи (принтер не поддерживает), перейти к печати в растровом виде. Растровую печать можно инициировать с помощью нового метода PrintBitmap.

PInvoke

В документации эта возможность пока не описана, но я знал, что она уже реализована – возможность вызова методов Windows API из Silverlight приложений, обладающих повышенными полномочиями. Причем речь идет о приложениях, которые работают как в браузере, так и вне браузера. Поскольку вызов нативных функций в .NET обычно осуществляется с помощью атрибута DllImport, то я решил попробовать этот механизм и тут (запустив приложение с повышенными привилегиями):

 

   1:  public partial class MainPage : UserControl
   2:  {
   3:    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
   4:    public static extern int MessageBox(IntPtr hWnd, 
   5:      String text, String caption, uint type);
   6:   
   7:    public MainPage()
   8:    {
   9:     MessageBox(new IntPtr(0), "Hello World!", "Hello Dialog", 0);
  10:     InitializeComponent();
  11:    }
  12:  }

 

Удивительно то, что оно заработало. На экране, поверх браузера я увидел стандартный MessageBox. Пользуйтесь!

Written by Sergiy Baydachnyy

05.09.2011 at 18:10

Опубликовано в SilverLight

Tagged with

Введение в Silverlight 5 (часть 3)

leave a comment »

Продолжаем рассматривать новые возможности Silverlight 5, тем более, что вчера появился Release Candidate. Прежде чем перейти к 3D и связыванию с данными, рассмотрим массу небольших нововведений, которые могут сделать жизнь разработчика более приятной.

Установка имени файла по умолчанию в SaveFileDialog

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

SaveFileDialog dialog = new SaveFileDialog();

dialog.DefaultFileName = "hello.txt";

dialog.ShowDialog();

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

Улучшение работы с аудио

В Silverlight 5 стала доступна библиотека по работе с Media. Классы этой библиотеки представлены пространством имен Microsoft.Xna.Framework.Audio. Нетрудно догадаться, что данный шаг выполнен в рамках интеграции с XNA библиотеками, которые можно использовать и в Silverlight (это аудио и 3D).

Новое пространство имен содержит два основных класса, позволяющих создавать аудио эффекты в процессе работы Silverlight приложения. Файлы, доступные для проигрывания, должны быть в формате WAV и могут быть загружены с помощью класса SoundEffect. Конструктор этого класса получает ссылку на набор данных и(или) настройки аудио.

Создание конкретного экземпляра можно также выполнить с помощью статического метода FromStream, получающего ссылку на поток в качестве параметров.

Проигрывание эффекта осуществляется с помощью метода Play. Каких-то других методов SoundEffect не имеет, но это вовсе не означает, что отдельно взятым объектом нельзя управлять. Так, если Вы хотите не просто воспроизвести эффект, но и добавить элементы управления аудио (громкость, пауза и т .д.), то вместо метода Play следует вызывать метод CreateInstance, создающий конкретный экземпляр на базе SoundEffect, и возвращающий ссылку типа SoundEffectInstance, которая позволит управлять нашим аудио файлом.

SoundEffect sEffect=SoundEffect.FromStream(streamInfo.Stream);

sEffect.Play();

Изменение скорости проигрывания медиа

В Silverlight 5 произошли улучшения и в MediaElement элементе. Теперь этот элемент управления содержит такое свойство как PlaybackRate и событие RateChanged. Свойство позволяет задавать скорость проигрывания видео, а событие – реагировать на изменение свойства.

Нужно отметить, что при тестировании свойства у меня проявилась странная бага в дизайнере: при изменении свойства PlaybackRate через окно свойств, оно остается неизменным, показывая значение 1. При этом в XAML файле оно модифицируется, как и положено.

 

image

 

Возможно, это только моя проблема (какие версии я тут только не ставил), но будьте готовы к такому поведению.

Поддержка пульта дистанционного управления

Не было возможности проверить данную функциональность, так как пульт к Media Center у меня отсутствует (или к Xbox), но, теоретически Silverlight 5 поддерживает и работу с пультом. Данная функциональность стала доступна благодаря поддержке события MediaCommand, которое доступно у всех UIElement. Иными словами, если Вы хотите обрабатывать нажатия кнопок пульта, то Вам следует обработать это событие у родительского контейнера (от дочерних элементов оно как раз туда и свалится). Чтобы понять, какая кнопка на пульте была нажата, обработчик события получает доступ к свойству в MediaCommandEventArgs, содержащему свойство перечислимого типа MediaCommand. Последнее и содержит информацию по нажатой кнопке.

Written by Sergiy Baydachnyy

03.09.2011 at 08:40

Опубликовано в SilverLight

Tagged with

Введение в Silverlight 5 (часть 2)

3 комментария

Повышение полномочий для приложений в браузере

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

Шаг 1. Приложение необходимо подписать сертификатом, что вполне можно сделать из оболочки Visual Studio в настройках проекта (вкладка Signing).

 

image

 

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

Шаг 2. Далее необходимо развернуть сертификат на машинах, где будет работать Ваше Silverlight-приложение. Если Вы хотите протестировать функциональность на рабочей машине, то это можно легко сделать, нажав кнопку More Details в диалоге выше, перейдя к параметрам сертификата:

 

image

Шаг 3. На следующем этапе нужно у всех клиентов разрешить запуск приложений в браузере с повышенными полномочиями. Это можно сделать, установив значение AllowElevatedTrustAppsInBrowser (DWORD) в 0х00000000 (disabled) или 0x00000001(enabled) в ключах HKEY_LOCAL_MACHINE\Software\Microsoft\Silverlight\ (для 32 бит) или HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Silverlight\ (для 64 бит).

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

 

image

 

После этих действий, Visual Studio сгенерирует дополнительный конфигурационный файл следующего содержимого:

 

   1:  <InBrowserSettings>
   2:     <InBrowserSettings.SecuritySettings>
   3:        <SecuritySettings ElevatedPermissions="Required" />
   4:     </InBrowserSettings.SecuritySettings>
   5:  </InBrowserSettings>

 

Вот и все. Теперь Ваши приложения (подписанные сертификатом), будут запускаться в браузере с дополнительными полномочиями, включая полную поддержку клавиатуры в полноэкранном режиме, поддержку элементов WebBrowser и NotificationWindow и др.

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

Поддержка нескольких окон

Для приложений с повышенными привилегиями, работающих вне браузера, стало возможным отображать несколько немодальных окон, которые могут перемещаться за пределы родительского окна, а также интегрируются с панелью задач Windows 7.

Ниже приведен небольшой код, который, внутри конструктора главного окна, генерирует дочернее окно и делает его видимым:

 

   1:  public MainPage()
   2:  {
   3:  InitializeComponent();
   4:   
   5:     Window childWindow = new Window();
   6:     childWindow.Height = 400;
   7:     childWindow.Width = 600;
   8:     childWindow.Top = 30;
   9:     childWindow.Left = 30;
  10:     childWindow.Title = "Child Window";
  11:     childWindow.Visibility = Visibility.Visible;
  12:  }

 

В данном примере дочернее окно создается с размерами 600 на 400, при этом верхний левый его угол будет находит в позиции (30, 30), относительно экрана системы (не родительского окна). При этом обратите внимание на то, что созданное окно поддерживается панелью задач Windows 7:

 

image

 

Доступ к файловой системе для приложений с повышенными привилегиями

Технология Silverlight 4 поддерживала возможность приложениям с повышенными привилегиями получать доступ к файловой системе пользователя. Правда, доступ был ограничен лишь несколькими папками. Так, в режиме с повышенными привилегиями, приложения получают полный контроль к специальным папкам, ассоциированными с пользователем: MyDocuments, MyVideos, MyPictures, MyMusic. Пути к указанным папкам можно получить, используя статический класс Environment. При этом нужно отметить, что SilverLight-приложение работает только с папками, но не с библиотеками (Windows 7).

В Silverlight 5 появилась возможность взаимодействовать со всей файловой системой пользователя. Речь идет как о чтении файлов, так и о записи.

Written by Sergiy Baydachnyy

30.08.2011 at 15:59

Опубликовано в SilverLight

Tagged with

Введение в Silverlight 5 (часть 1)

with one comment

Закончилась очередная конференция MIX (http://live.visitmix.com), на которой, традиционно, была представлена новая версия технологии Silverlight – 5-я версия. Несмотря на то, что в Silverlight 5 beta доступны еще не все ожидаемые возможности, я, также традиционно, начну обзор существующих.

Начну с того, что Silverlight 5 beta можно скачать по ссылке http://www.silverlight.net/getstarted/silverlight-5-beta/. Тут доступны: видео презентации с обзором новых возможностей, статьи и инсталляция Silverlight 5 beta утилиты для Visual Studio 2010 SP1.

Обработка множественного нажатия кнопки мыши

Первая возможность, с которой мы начнем обзор, это поддержка обработки множественного нажатия кнопки мыши. Обычно требуется реализовать обработчик события при двойном щелчке, но Silverlight позволяет обрабатывать и большее количество нажатий. Речь идет как о левой, так и о правой кнопках мыши. Тут разработчики немного схитрили. Чтобы не менять модель событий и не вводить новые события на двойной щелчок мыши, к параметру EventArgs уже существующих событий, возникающих при однократном нажатии кнопки мыши, было добавлено свойство ClickCount. Это свойство и содержит количество нажатий.

Интересно то, что события MouseLeftButtonDown и MouseRightButtonDown срабатывают для каждого щелчка, даже если вы хотите обрабатывать только двойной щелчок. При этом, если между щелчками проходит больше секунды, или другое событие (например, пользователь еще и потянул мышь), то счетчик обнуляется. Поэтому, если Вы хотите для одного и того же объекта обрабатывать одинарный и двойной (а может и тройной) щелчок, то необходимо, чтобы они не были взаимоисключающими. Иными словами, при одинарном щелчке Вы можете выбрать папку, а при двойном – открыть папку. Наоборот работать не будет, так как уже при первом щелчке папка будет открыта.

Ниже показан простой код, который позволяет отобразить количество щелчков:

   1:  <Grid x:Name="LayoutRoot" Background="White" 
   2:     MouseLeftButtonDown="LayoutRoot_MouseLeftButtonDown">
   3:     <sdk:Label Height="28" HorizontalAlignment="Left" 
   4:        Name="label1" VerticalAlignment="Top" Width="120" />
   5:  </Grid>

 

Поддержка выбора элементов в ItemsControl с клавиатуры

Данный функционал достаточно простой, но приятный. Вспомните бесконечные элементы ComboBox со списком стран, или элементы, позволяющие установить фильтр по чьей-то фамилии, выбрав ее из сотни других и т. д. Для всех этих случаев, имея элемент-наследник от ItemsControl, такой как ListBox, ComboBox и другие, Вы всегда должны были пользоваться скроллингом, чтобы найти нужный элемент. Естественно, я имею в виду Silverlight. В WPF или даже в простом HTML, подобные элементы давно поддерживают возможность выбора с клавиатуры. Так, переходя на тот же выпадающий список стран, мне достаточно легко набрать на клавиатуре букву «У», чтобы увидеть активным элементом слово «Украина». Это позволяет быстро заполнять сложные формы с большим количеством опций. Теперь такая возможность появилась и в Silverlight. Рассмотрим простой пример:

   1:      <Grid x:Name="LayoutRoot" Background="White">
   2:          <ComboBox Height="23" HorizontalAlignment="Left" 
   3:              Name="comboBox1" VerticalAlignment="Top" Width="120">
   4:              <ComboBoxItem Content="Последний" />
   5:              <ComboBoxItem Content="Третий" />
   6:              <ComboBoxItem Content="Второй" />
   7:              <ComboBoxItem Content="Первый" />
   8:          </ComboBox>
   9:      </Grid>

 

На экране отобразится обычный ComboBox, который позволяет выбрать один из четырех элементов. Переключитесь на русскую клавиатуру и попробуйте понажимать символ «П». ComboBox будет последовательно выбирать один из двух элементов (Первый и Последний). Если Вы последовательно наберете два символа, например «Пе», то будет выбран «Первый» без альтернатив.

Понятно, что ComboBox в Silverlight, как и другие ItemsControl, позволяет отображать что угодно и не обязательно текст, особенно если речь идет о связывании со сложными объектами. Именно поэтому, для всех элементов ItemsControl ввели дополнительное свойство TextPath, которое задает имя свойства объекта, с которым мы реализуем связывание, используемое при выборе элемента с клавиатуры.

   1:  <ComboBox Height="23" TextSearch.TextPath="ImageTitle" 
   2:     HorizontalAlignment="Left" Name="comboBox1" 
   3:     VerticalAlignment="Top" Width="120">

Written by Sergiy Baydachnyy

14.04.2011 at 18:15

Опубликовано в SilverLight

Tagged with

Обзор Silverlight 5

3 комментария

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

Итак, Silverlight 5 – технология для построения Web-приложений с «богатым» интерфейсом (RIA) станет доступна разработчикам уже в начале апреля (естественно в бета версии). Планируется, что Silverlight 5 представят в ходе конференции MIX 11. Релиз же станет доступен осенью. Тем не менее, постараюсь дать обзор прямо сейчас.

Поддержка 64-битной платформы

Даже Silverlight 4 не работает в 64-битных браузерах. Между тем, 32-бита уверенно уходят в прошлое. Именно поэтому, начиная с 5-й версии Silverlight, плагин будет доступен как в 32-битной, так и в 64-битной версиях. Предполагается, что пользователю не придется думать, какая из версий должна быть установлена.

Управление скоростью проигрывания видео

Функционал позволит устанавливать скорость проигрывания, синхронизируя видео и звук, а также выполнять «переметку» не только вперед, но и назад. Предполагается, что можно будет использовать следующие множители для скорости проигрывания: 0.2, 0.4, 0.6, 0.8, 1, 2, 4, 8, 16, 32.

Интеграция с пультом управления

Сегодня, такие приложения, как Windows Media Center, успешно работают с пультом, позволяющим управлять программой, не вставая с кровати. Silverlight 5 будет поддерживать аналогичные возможности.

Улучшенное управление питанием

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

Двойной щелчок мышью

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

Копирование изображений

В Silverlight 4 появился класс Clipboard, который позволил копировать текст в буфер и обратно. Silverlight 5 расширяет возможности этого класса, позволяя работать с изображениями. Методы SetImage и GetImage будут работать с объектами типа BitmapSource. Также предусмотрено наличие метода ContainsImage, проверяющего наличие изображения в буфере.

Поддержка 3D

Речь идет не о технологии псевдо 3D, появившейся в Silverlight 4, а о полноценном 3D API с поддержкой аппаратного ускорения. Последнее уже хорошо зарекомендовало себя при работе с видео.

Поддержка Behaviors и Triggers

Поддержка Behaviors призвана перенести функциональность Поведений, реализованных в Blend на уровень ядра Silverlight. Речь идет о создании комплексных объектов, объединяющих в себе ряд различных преобразований, создавая тем самым уникальное Поведение. И если ранее подобное можно было реализовать, только подключив специальную сборку из Blend, то теперь это все будет в ядре. Введение триггеров призвано еще больше сблизить WPF и Silverlight, хотя триггера в Silverlight выглядят более универсальными.

Улучшенное отображение текста

Для начала, в элементах TextBlock появится возможность устанавливать интервал между символами и строками. Появится полная поддержка OpenType. Кроме того, планируются значительно улучшить элемент RechText, добавив туда новые возможности (хоть он мне и не нравится).

Layout transition

В Silverlight 5 любому контейнеру будет можно задавать эффекты, связанные с заполнением контейнера и добавлением нового элемента. Благодаря Layout transition разработчику не придется работать с каждым элементом отдельно, а достаточно будет указать механизм заполнения для всего контейнера.

Связывание с данными: Отладка

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

Связывание с данными: FindAncestor

Вспоминаю дискуссию в одном из своих постов о Silverlight 3 (http://dev.net.ua/blogs/sergiybaydachnyy/archive/2009/04/13/8103.aspx). Народ очень хотел FindAncestor. НатеJ RelativeSource FindAncestor позволяет выполнять связку, выполняя поиск любого вышестоящего элемента и выполнять с ним связывание.

Связывание с данными: DataContextChanged

Как видно, Silverlight 5 все ближе и ближе приближается к WPF. Новое событие DataContextChanged позволит определить изменение источника данных при связывании.

Связывание с данными: Стили

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

Дочерние окна

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

Поддержка Full-Trust внутри браузера

Silverlight 5 будет поддерживать правила, установленные групповыми политиками. Поддержка групповых политик позволит централизовано управлять развертыванием Silverlight-приложений. Кроме того, это даст возможность устанавливать список Publishers (вылетело русское слово из головы), разрешая избранным приложениям работать внутри браузера, но с использованием Full-Trust со всеми вытекающими последствиями (включая поддержку элемента WebBrowser). Это нововведение связано с отзывом от некоторых компаний, которые хотят запускать свои корпоративные приложения внутри браузера, но с повышенными привилегиями.

P/Invoke

Да, да, речь идет именно о возможности вызова Win API функций. Естественно, это будет работать в режиме Full-Trust. Фактически, теперь Silverlight 5 сможет делать все, что угодно.

Вроде бы все. Если что и забыл, то смотрите анонс Скотта по следующей ссылке: http://www.silverlight.net/news/events/firestarter/

Written by Sergiy Baydachnyy

16.02.2011 at 20:25

Опубликовано в SilverLight

Tagged with

Начинаем разрабатывать для Windows Phone 7: Настройка клавиатуры

with one comment

Чтобы почувствовать дух Windows Phone 7 и посмотреть на различия в подходах построения обычных Silverlight- и Windows Phone приложений, рассмотрим несколько небольших примеров.

Пример 1. Управление клавиатурой

Начнем с простого элемента управления TextBox, который позволяет вводить текст. В обычной реализации этот элемент ничем особым не выделяется. Но если говорить о Windows Phone 7, то вопрос ввода очень существенен. Так, двигаясь со скоростью 130-160 км/ч, мне очень затруднительно делать ввод данных на наших дорогах. Поэтому моим простым желанием является то, чтобы клавиатура содержала только тот набор элементов, который нужен мне в данном контексте. То есть, если я ввожу телефонный номер, то я должен видеть только цифры, а если я переписываюсь в месенджере, то мне необходимы не только буквы, но и специальные символы. В идеале я бы хотел иметь и проверку орфографии. Все эти возможности в Windows Phone 7 присутствуют. И если проверка орфографии выполняется автоматически, то управлять клавиатурой при вводе текста можно с помощью простого свойства InputScope элемента TextBox.

Ниже показан простой пример, «настраивающий» элемент TextBox для ввода электронного адреса:

<TextBox>
    <TextBox.InputScope>
        <InputScope>
            <InputScopeName NameValue="EmailUserName"></InputScopeName>
        </InputScope>
    </TextBox.InputScope>
</TextBox>

 

В результате на экране будет появляться следующая клавиатура:

clip_image002

@17.4 Ввод электронного адреса

 

Подобный код можно реализовать и программно, настраивая элементы TextBox динамически:

 

txtBox.InputScope = new InputScope()
{
    Names = 
    {
        new InputScopeName()
        {
            NameValue = InputScopeNameValue.EmailUserName
        }
    }
};

Written by Sergiy Baydachnyy

24.06.2010 at 10:23

Опубликовано в SilverLight, Windows Phone

Tagged with