Обработка события изменения размера окна в Silverlight 2

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

Оповещатель о событии находится в классе App:

App.Current.Host.Content.Resized

Нужно просто привязать к нему обработчик, например, после загрузки приложения:

void Page_Loaded(object sender, RoutedEventArgs e)
 {
     App.Current.Host.Content.Resized += 
         new EventHandler(Content_Resized);
}

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

SLResizeSample

Итак, создаем новый проект и добавляем две StackPanel. Вот полный XAML-код:

<UserControl x:Class="WindowResize.Page"
    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 x:Name="menuVertical" 
                    VerticalAlignment="Top"
                    HorizontalAlignment="Left"
                    Width="100">
            <Button Content="Кнопка Меню" />
            <Button Content="Кнопка Меню" />
            <Button Content="Кнопка Меню" />
            <Button Content="Кнопка Меню" />
            <Button Content="Кнопка Меню" />
        </StackPanel>
        <!-- Горизонтальная панель -->
        <StackPanel x:Name="menuHorizontal"
                    Margin="100,0,0,0"
                    Orientation="Horizontal"
                    Height="50"
                    VerticalAlignment="Top"
                    HorizontalAlignment="Left" >
            <Button Content="Кнопка Меню" />
            <Button Content="Кнопка Меню" />
            <Button Content="Кнопка Меню" />
            <Button Content="Кнопка Меню" />
            <Button Content="Кнопка Меню" />
        </StackPanel>
    </Grid>
</UserControl>

Код C# с подробными комментариями:

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 WindowResize
{
    public partial class Page : UserControl
    {
        public Page()
        {
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(Page_Loaded);
        }

        void Page_Loaded(object sender, RoutedEventArgs e)
        {
            //Привязываем обработчик
            App.Current.Host.Content.Resized += 
                new EventHandler(Content_Resized);
        }

        void Content_Resized(object sender, EventArgs e)
        {
            //По изменению размера окна браузера,
            //вызываются соответсвующие функции для
            //перерасчета высоты или ширины каждого
            //элемента в панелях
            ResizeHorizontalMenu();
            ResizeVerticalMenu();
            
        }
        void ResizeVerticalMenu()
        {
            //Вычисляется новая высота для каждой 
            //кнопки. LayoutRoot - родительский
            //контрол, в котором располагаются все остальные 
            //визуальные элементы. Он занимает все окно, так
            //как специально не были заданы его ширина и высота.
            //Чтобы получить его реальную высоту (т.е. 
            //ту высоту, которая отображается пользователю)
            //можно воспользоваться свойством ActualHeight.
            //Далее делим всю высоту на количество
            //элементов в панели меню.
            double newHeight = LayoutRoot.ActualHeight /
                (double)menuVertical.Children.Count;
            //Для каждой кнопки в панели задаем
            //новое значение высоты
            foreach (UIElement el in menuVertical.Children)
            {
                Button btn = el as Button;
                btn.Height = newHeight;
            }
        }
        void ResizeHorizontalMenu()
        {
            //То же самое, что и с вертикальной панелью,
            //только сделана поправка на горизонтальный
            //отступ, который равен ширине вертикальной
            //панели
            double menuHorizontalMarginLeft = 
                menuVertical.ActualWidth;
            double newWidth = (LayoutRoot.ActualWidth - 
                menuHorizontalMarginLeft) /
                (double)menuHorizontal.Children.Count;
            foreach (UIElement el in menuHorizontal.Children)
            {
                Button btn = el as Button;
                btn.Width = newWidth;
            }
        }
    }
}

Из комментариев должно быть все понятно. Посмотреть на пример можно тут - http://silverlight.services.live.com/invoke/36889/WindowResize/iframe.html

Posted on 21.08.2008 18:23:35 by admin

Permalink | Комментарии (0) | Post RSSRSS comment feed |

Categories: Silverlight

Tags: , ,

Оценок нет

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Создание PasswordBox в Silverlight

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

Нужно всего лишь заменить стандартный шрифт текстбокса на специльный, в котором все символы заменены каким-то одним, например, кружочком или звездочкой. При этом, считывая пароль, мы получаем обычный текст. Делается это через свойство FontFamily, в формате "имя файла со шрифтами#название шрифта":

<TextBox FontFamily="/slpassword.ttf#SLPassword"/>

Посмотрим на пример:

В Silverlight проект нужно добавить файл шрифта slpassword.ttf и назначить ему свойство BuildAction - Content:

 slpass_as_content

XAML-код примера:

<UserControl x:Class="PasswordBox.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="400" Height="120">
    <Grid x:Name="LayoutRoot" Background="White">
        <StackPanel Orientation="Vertical">
            <TextBox x:Name="passBox" Height="60" FontSize="40"
                     FontFamily="/slpassword.ttf#SLPassword"/>
            <ToggleButton Height="60"
                          Unchecked="ToggleButton_Unchecked"
                          Checked="ToggleButton_Checked"
                          Content="Показать/скрыть пароль" />
        </StackPanel>
    </Grid>
</UserControl>

Содержимое Page.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;
using System.IO;

namespace PasswordBox
{
    public partial class Page : UserControl
    {
        public Page()
        {
            InitializeComponent();
        }
       
        private void ToggleButton_Unchecked(object sender, RoutedEventArgs e)
        {
            passBox.FontFamily = new FontFamily("/slpassword.ttf#SLPassword");
        }

        private void ToggleButton_Checked(object sender, RoutedEventArgs e)
        {
            passBox.FontFamily = new FontFamily("Trebuchet MS");
        }
    }
}

Как видите, не пришлось писать никаких классов и создавать новый контрол, как говорится, все гениальное просто :)

Русифицированный файл со шрифтом - slpassword.ttf

Posted on 17.08.2008 21:46:24 by admin

Permalink | Комментарии (0) | Post RSSRSS comment feed |

Categories:

Tags: , , ,

Оценок нет

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5