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

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

Archive for Январь 2010

Введение в SilverLight 4: Неявные стили

leave a comment »

На этот раз рассмотрим возможность, облегчающую работу при построении интерфейса приложения.

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

То есть стиль мог выглядеть следующим образом:

<Style TargetType="Button" x:Key="btnStyle">
 <Setter Property="FontFamily" Value="Arial Black"></Setter>
 <Setter Property="Background" Value="Green"></Setter>
 <Setter Property="FontStyle" Value="Italic"></Setter>
 <Setter Property="Foreground" Value="Red"></Setter>
</Style>

А код, устанавливающий стиль для конкретного элемента мог выглядеть так:

<Button Style="{StaticResource btnStyle}" 
 Content="Hello" Width="100" Height="50"></Button>

Теперь, при определении стиля, от атрибута x:Key можно избавится. Это будет означать, что указанный стиль будет использован неявно для всех элементов заданного типа. Естественно, если в элементе прописать стиль явно, то неявный стиль для этого элемента будет игнорироваться.

Written by Sergiy Baydachnyy

15.01.2010 at 08:02

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

Tagged with

MultiPoint SDK 1.5

leave a comment »

Появилась новая версия MultiPoint Mouse SDK, позволяющая разрабатывать Windows-приложения, поддерживающие несколько мышек одновременно.

Теперь версия 1.5 полностью поддерживает Windows 7.

На следующей неделе мы планируем анонсировать конкурс для украинских студентов на лучшее приложение, использующее MultiPoint SDK 1.5. Хорошие призы гарантирую.

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

http://www.microsoft.com/multipoint/mouse-sdk/

Written by Sergiy Baydachnyy

14.01.2010 at 15:37

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

Tagged with

Введение в SilverLight 4: Работа с камерой и микрофоном

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

Еще одна потрясающая возможность SilverLight 4, это поддержка камеры и микрофона. Чтобы показать эти возможности в действии, рассмотрим небольшой пример. Для этого создадим новый SilverLight-проект и реализуем следующий интерфейс:

<UserControl x:Class="WebCam_Chapter0.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <StackPanel x:Name="LayoutRoot" Background="White" 
        Loaded="LayoutRoot_Loaded">
        <Rectangle Width="400" Height="300" Fill="Gray" 
            Name="videoContainer">
        </Rectangle>
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
            <StackPanel>
                <TextBlock Text="Video Devices" Margin="5"></TextBlock>
                <ListBox Height="30" Name="videoBox">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <TextBlock 
                             Text="{Binding FriendlyName}">
                            </TextBlock>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </StackPanel>
            <StackPanel>
                <TextBlock Text="Audio Devices" Margin="5"></TextBlock>
                <ListBox Height="30" Name="audioBox">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <TextBlock 
                             Text="{Binding FriendlyName}">
                            </TextBlock>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </StackPanel>
        </StackPanel>
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
            <Button Content="Start" Width="100" Height="30" 
                Click="Start_Click" Margin="5"></Button>
            <Button Content="Stop" Width="100" Height="30" 
                Click="Stop_Click" Margin="5"></Button>
            <Button Content="Capture" Width="100" Height="30" 
                Margin="5" Click="Capture_Click"></Button>
        </StackPanel>
        <ScrollViewer Width="500" Height="200" 
            HorizontalScrollBarVisibility="Visible" 
            VerticalScrollBarVisibility="Hidden">
            <ItemsControl Name="imageContainer">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Image Source="{Binding}" 
                         Stretch="UniformToFill" 
                         Height="150" Margin="5">
                        </Image>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Horizontal" 
                         VerticalAlignment="Center" 
                         HorizontalAlignment="Center">
                        </StackPanel>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl>
        </ScrollViewer>
    </StackPanel>
</UserControl>

Предложенный интерфейс будет выглядеть так, как на рисунке ниже:

image

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

Итак, получить аудио и видео потоки можно с помощью класса CaptureSource. Структура этого класса достаточно простая, так, тут можно выделить два всего два основных метода и три основных свойства:

· Start – инициирует доступ объекта типа CaptureSource к аудио и видео потокам;

· Stop – закрывает доступ к видео и аудио потокам;

· VideoCaptureDevice – задает устройство для получения видео потока;

· AudioCaptureDevice – задает устройство для получения аудио потока;

· State – определяет состояние объекта типа CaptureSource: Started – запушен и получает потоки; Stopped – остановлен; Failed – проблемы с подключением.

Таким образом, чтобы приступить к работе с видео и аудио, необходимо создать объект типа CaptureSource:

private CaptureSource _source = new CaptureSource();

Прежде, чем запустить работу с потоками, необходимо выбрать и установить устройства. Для этих целей используется класс CaptureDeviceConfiguration, содержащий несколько статических методов:

· GetAvailableAudioCaptureDevices – возвращает список доступных аудио устройств (как набор объектов типа AudioCaptureDevice);

· GetAvailableVideoCaptureDevices – возвращает список доступных видео устройств (как набор объектов типа VideoCaptureDevice);

· GetDefaultAudioCaptureDevice – возвращает устройство по умолчанию;

· GetDefaultVideoCaptureDevice – возвращает устройство по умолчанию.

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

audioBox.ItemsSource = 
  CaptureDeviceConfiguration.GetAvailableAudioCaptureDevices();
videoBox.ItemsSource = 
  CaptureDeviceConfiguration.GetAvailableVideoCaptureDevices();

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

_source.VideoCaptureDevice = (VideoCaptureDevice)videoBox.SelectedItem;
_source.AudioCaptureDevice = (AudioCaptureDevice)audioBox.SelectedItem;

Теперь наша задача использовать CaptureSource для вывода видео на экран. Для этого мы и будем использовать элемент Rectangle и объект типа VideoBrush для его заливки:

VideoBrush vBrush = new VideoBrush();
vBrush.SetSource(_source);
videoContainer.Fill = vBrush;

Создав объект типа CaptureSource и установивив все необходимые параметры, можно приступать к вызову метода Start. Но, прежде чем сделать это, необходимо проверить, имеет ли приложение права на доступ к устройствам, а если не имеет, то права необходимо запросить у пользователя. Проверить наличие прав и запросить доступ можно с помощью уже знакомого класса CaptureDeviceConfiguration. Для этого используется свойство AllowedDeviceAccess и метод RequestDeviceAccess соответственно. Таким образом, код, выполняющий запуск объекта типа CaptureSource, должен выглядеть следующим образом:

    if (CaptureDeviceConfiguration.AllowedDeviceAccess 
       || CaptureDeviceConfiguration.RequestDeviceAccess())
    {
        _source.Start();
    }

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

private CaptureSource _source = new CaptureSource();
private ObservableCollection<WriteableBitmap> _images = 
    new ObservableCollection<WriteableBitmap>();
 
public MainPage()
{
    InitializeComponent();
}
 
private void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
{
    audioBox.ItemsSource = 
      CaptureDeviceConfiguration.GetAvailableAudioCaptureDevices();
    videoBox.ItemsSource = 
      CaptureDeviceConfiguration.GetAvailableVideoCaptureDevices();
 
    if ((videoBox.Items.Count > 0) && (audioBox.Items.Count > 0))
    {
        videoBox.SelectedIndex = 0;
        audioBox.SelectedIndex = 0;
    }
 
    imageContainer.ItemsSource = _images;
}
 
private void Stop_Click(object sender, RoutedEventArgs e)
{
    _source.Stop();
}
 
private void Start_Click(object sender, RoutedEventArgs e)
{
    if ((videoBox.Items.Count==0)||(audioBox.Items.Count==0))
    {
        MessageBox.Show("Audio or Video device is not available");
        return;
    }
 
    _source.VideoCaptureDevice = (VideoCaptureDevice)videoBox.SelectedItem;
    _source.AudioCaptureDevice = (AudioCaptureDevice)audioBox.SelectedItem;
 
    VideoBrush vBrush = new VideoBrush();
    vBrush.SetSource(_source);
 
    videoContainer.Fill = vBrush;
 
    if (CaptureDeviceConfiguration.AllowedDeviceAccess 
       || CaptureDeviceConfiguration.RequestDeviceAccess())
    {
        _source.Start();
    }
}
 
private void Capture_Click(object sender, RoutedEventArgs e)
{
    if (_source.State == CaptureState.Started)
    {
        _source.AsyncCaptureImage(CaptureImage<WriteableBitmap>);
    }
}
 
private void CaptureImage<WriteableBitmap>(
    System.Windows.Media.Imaging.WriteableBitmap t)
{
    _images.Add(t);
}

При запуске данного приложения должно получится что-то такое (если Вы увидете свое лицо, то не расстраивайтесь, так задумано):

image

В завершении хочу отметить два класса: AudioSink и VideoSink, которые позволяют получить доступ к видео и аудио как к набору байтов. Оба класса абстрактные, поэтому от разработчика потребуется определить собственные классы и несколько методов.

Written by Sergiy Baydachnyy

14.01.2010 at 15:01

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

Tagged with

football.ua опубликовал свой тулбар на SilverLight

with one comment

Сегодня на сайте football.ua появилась кастом версия браузера IE 8, которая включает в себя специально подготовленный для football.ua тулбар. Тулбар использует SilverLight 3 для отображения данных.

Смотрим:

http://football.ua/ie8/

Written by Sergiy Baydachnyy

14.01.2010 at 14:55

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

Tagged with

Введение в SilverLight 4: Элемент управления ViewBox

with one comment

Чтобы продемонстрировать работу нового элемента управления ViewBox, достаточно рассмотреть небольшой пример:

<UserControl x:Class="ViewBox_Chapter0.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid x:Name="LayoutRoot" Background="White">
        <StackPanel>
            <Button Content="Hello" Width="400" Height="100"></Button>
        </StackPanel>
    </Grid>
</UserControl>

Если попробовать запустить приложение выше, и изменить размер окна браузера, то можно увидеть что размер кнопки остается неизменным. Если изменить размер окна браузера, сделав его меньшим размера кнопки, то она попросту перестанет влазить на экран. Таким образом, существует проблема изменения размеров интерфейса при изменении размеров окна браузеров. Конечно, данную проблему можно решить с помощью элемента компоновки Grid, но при работе со сложными интерфейсами, элемент Grid не помогает. Поэтому появление элемента ViewBox, позволяющего сжимать и расширять свое содержимое, является даже запоздалым.

Замечание. Элемент ViewBox был доступен и разработчикам более ранней версии SilverLight, но не входил в стандартную поставку, а поставлялся в составе специальной библиотеки с открытым кодом, разрабатываемой сообществом.

Рассмотрим пример выше, но добавим элемент компоновки ViewBox:

<UserControl x:Class="ViewBox_Chapter0.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid x:Name="LayoutRoot" Background="White">
        <Viewbox MaxHeight="200" MaxWidth="800" 
            MinHeight="50" MinWidth="200">
            <StackPanel>
                <Button Content="Hello" Width="400" Height="100"></Button>
            </StackPanel>
        </Viewbox>
    </Grid>
</UserControl>

Теперь, при изменении размеров окна браузера, также изменяется и размер нашей кнопки.

Рассмотрим элемент ViewBox более детально. Фактически тут можно выделить всего три основных свойства: Child, Stretch, StretchDirection.

Свойство Child содержит ссылку на тот элемент, размерами которого управляет ViewBox. Тут может быть только один элемент, но это может быть и контейнер (как в примере выше).

Свойство Stretch определяет, каким образом содержимое ViewBox размещается внутри выделенного пространства. Тут возможно одно из следующих значений:

· None – сохранять исходный размер контента;

· Fill – полностью заполнить элемент ViewBox, не сохраняя пропорции;

· Uniform – сохранять пропорции контента;

· UniformToFill – полностью заполнить элемент ViewBox, с сохранением пропорций контента. Естественно, что с этим параметром, в большинстве случаев, весь контент отобразить не удается и он выходит за границы ViewBox.

Последнее свойство StretchDirection позволяет разрешить только сжатие или расширение содержимого и принимает одно из значений:

· UpOnly – только расширять контент, если размер ViewBox больше размера самого контента;

· DownOnly – только сжимать контент, если размер ViewBox меньше размера самого контента;

· Both – позволяет расширять и сжимать контент (установлено по умолчанию).

Таким образом, в SilverLight 4 на один полезный элемент компоновки стало больше.

Written by Sergiy Baydachnyy

12.01.2010 at 10:28

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

Tagged with

Введение в SilverLight 4: Поддержка колесика мыши

leave a comment »

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

Реализуем простое приложение, интерфейс которого содержит изображение, к которому мы применим трехмерную проекцию по оси X. Вот код интерфейса приложения:

<UserControl x:Class="MouseWheel_Chapter0.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
> 
    <Grid x:Name="LayoutRoot" Background="White">
        <Image Source="Penguins.jpg" Width="640" 
            Height="480" MouseWheel="Image_MouseWheel">
            <Image.Projection>
                <PlaneProjection x:Name="proj"></PlaneProjection>
            </Image.Projection>
        </Image>
    </Grid>
</UserControl>

Как видно, тут мы определили обработчик события MouseWheel, которое генерируется именно при вращении колесика мыши. Код обработчика довольно простой:

private void Image_MouseWheel(object sender, MouseWheelEventArgs e)
{
    proj.RotationX += e.Delta/10;
}

Запустите приложение, щелкните на картинке и начните вращать колесико мыши – картинка будет вращаться вокруг оси X.

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

Written by Sergiy Baydachnyy

12.01.2010 at 07:47

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

Tagged with

Введение в SilverLight 4: Поддержка уведомлений

with one comment

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

Чтобы отобразить уведомление, достаточно создать объект типа NotificationWindow и установить свойство Content у созданного объекта. Свойство Content принимает любой объект, порожденный от FrameworkElement, то есть любой контейнер. После установки свойств Content, Width, Height, достаточно вызвать метод Show, принимающий время показа окна в миллисекундах.

Рассмотрим пример приложения, работающего вне браузера и отображающего примитивное окно в момент запуска. Интерфейс приложения реализуем следующим образом:

<UserControl x:Class="Notify_Chapter0.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid x:Name="LayoutRoot" Background="White">
        <StackPanel HorizontalAlignment="Center">
            <TextBlock Text="Notification Demo" 
               TextAlignment="Center" FontSize="18">
            </TextBlock>
            <Button Name="btn" Visibility="Collapsed" 
               Content="Инсталировать приложение" FontSize="18" 
               Click="Button_Click"></Button>
            <TextBlock Name="txt" Visibility="Collapsed" 
               TextWrapping="Wrap" TextAlignment="Center" 
               Text="Приложение должно быть запущено вне браузера" 
               FontSize="18">
            </TextBlock>
        </StackPanel>
    </Grid>
</UserControl>

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

public MainPage()
{
    InitializeComponent();
 
    if (App.Current.IsRunningOutOfBrowser)
    {
        NotificationWindow notify = new NotificationWindow();
        
        StackPanel panel = new StackPanel();
        panel.Background = new SolidColorBrush(Colors.Gray);
        panel.Width = 250;
        panel.Height = 50;
 
        TextBlock header = new TextBlock();
        header.Text = "New message";
        header.FontWeight = FontWeights.Bold;
 
        TextBlock message = new TextBlock();
        message.Text = "This is a new message";
 
        panel.Children.Add(header);
        panel.Children.Add(message);
 
        notify.Content = panel;
        notify.Width = panel.Width;
        notify.Height = panel.Height;
        notify.Show(10000);
    }
    else
    {
        if (App.Current.InstallState == InstallState.Installed)
        {
            txt.Visibility = Visibility.Visible;
        }
        else
        {
            btn.Visibility = Visibility.Visible;
        }
    }
}
 
private void Button_Click(object sender, RoutedEventArgs e)
{
    App.Current.Install();
}

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

clip_image002

Как видно, уведомление отображается в системной области с небольшим отступом от нее (по 44 единицы).

Данная функциональность может быть полезна при обработке обновлений, коммуникациях, асинхронной обработке данных и др.

Written by Sergiy Baydachnyy

11.01.2010 at 15:18

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

Tagged with