Размеры страницы

165

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

Верхнеуровневый контейнер каждой страницы Silverlight — это пользовательский класс, производный от класса UserControl. Класс UserControl добавляет в базовую структуру элементов Silverlight единственное свойство Content (Содержимое). Ему нужно присвоить один элемент, который становится содержимым объекта UserControl.

Объект UserControl не содержит никаких специальных средств. Это всего лишь удобный способ группирования элементов. Однако способ установки размеров элемента UserControl влияет на внешний вид всего пользовательского интерфейса, поэтому его нужно рассмотреть подробнее.

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

Фиксированные размеры

Установив свойства Width (Ширина) и Height (Высота) элемента UserControl, можно задать точные размеры страницы. Если размеры элементов управления, размещенных на странице, больше значений Width и Height, они будут отсечены. При фиксированных размерах окна свойствам HorizontalAlignment и VerticalAlignment элемента UserControl обычно присваивают значения Center, чтобы страница находилась посредине окна браузера, а не примыкала к левому верхнему углу.

Размеры окна браузера

Если удалить свойства Width и Height, страница займет все пространство, выделенное для нее в области содержимого Silverlight. По умолчанию программа Visual Studio создает входную страницу с такими размерами, что область содержимого Silverlight занимает все окно браузера. При использовании этого метода можно создавать элементы, выходящие за пределы области содержимого, однако тогда пользователю придется вручную увеличить размеры окна браузера, чтобы увидеть все содержимое. Иногда при использовании этого метода нужно оставить пустое пространство между страницей и краем окна браузера. Это можно сделать с помощью свойства Margin элемента UserControl.

Ограничение размеров

Вместо свойств width и Height можно применить свойства MaxWidth, MaxHeight, MinWidth и MinHeight. Тогда размеры элемента UserControl будут автоматически устанавливаться в пределах заданного диапазона таким образом, чтобы он поместился в окне браузера. При перетаскивании границы окна браузера размеры объекта UserControl будут изменяться до определенного момента времени, пока окно не станет слишком большим или маленьким. После этого размеры объекта UserControl перестанут изменяться, благодаря чему содержимое всегда остается разборчивым.

Неограниченные размеры

Иногда желательно позволить области содержимого Silverlight иметь размеры больше окна браузера. В этом случае браузер выведет на экран полосы прокрутки, как для обычной страницы HTML. Для вывода полос прокрутки нужно удалить свойства Width и Height и отредактировать входную страницу TestPage.html. На входной странице удалите атрибуты width="100%" и Height="100%" элемента <object>. Тогда области содержимого будет позволено увеличиваться до тех пор, пока в ней не поместятся все элементы управления.

Не забывайте, что инструменты разработки Visual Studio и Expression Blend могут добавить в пользовательский элемент управления атрибуты DesignWidth и DesignHeight. Они влияют на вывод страницы в среде разработки (аналогично свойствам Width и Height). Во время выполнения они игнорируются. Их главное назначение — облегчить создание пользовательских интерфейсов, учитывающих модель установки размеров браузерами, предоставляя в то же время реалистичный вид интерфейса в рабочей среде Visual Studio или Expression Blend.

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

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

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

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

Прокрутка

Ни один из пяти базовых контейнеров компоновки не поддерживает прокрутку, хотя она является наиболее мощным средством отображения большого объема информации в ограниченном пространстве. На платформе Silverlight добавить прокрутку несложно, однако для этого необходим дополнительный компонент — элемент управления ScrollViewer.

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

<UserControl x:Class="SilverlightTest.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Margin="20">

    <ScrollViewer Background="AliceBlue" VerticalScrollBarVisibility="Auto">
        <Grid Margin="3,3,10,3">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"></RowDefinition>
                ...
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"></ColumnDefinition>
                <ColumnDefinition Width="Auto"></ColumnDefinition>
            </Grid.ColumnDefinitions>

            <TextBox Grid.Row="0" Grid.Column="0" Margin="3"
                   Height="Auto" VerticalAlignment="Center"></TextBox>
            <Button Grid.Row="0" Grid.Column="1" Margin="3" Padding="2"
				   Content="Обзор"></Button>

            <TextBox Grid.Row="1" Grid.Column="0" Margin="3"
                   Height="Auto" VerticalAlignment="Center"></TextBox>
            <Button Grid.Row="1" Grid.Column="1" Margin="3" Padding="2"
				   Content="Обзор"></Button>

            ...
            
        </Grid>
    </ScrollViewer>
</UserControl>
Страница с полосой прокрутки

Если путем перетаскивания увеличить размер окна браузера таким образом, чтобы в контейнере Grid поместилось все содержимое, полоса прокрутки будет отключена, но она все же останется видимой на экране. Сделать ее невидимой можно с помощью свойства VerticalScrollBarVisibility, которое может принимать одно из значений перечисления ScrollBarVisibility. По умолчанию установлено значение Visible, при котором вертикальная полоса прокрутки всегда видна. При значении Auto полоса прокрутки выводится, когда она нужна, и скрывается, когда не нужна. При значении Disabled полоса прокрутки не выводится никогда.

Можно также установить значение Hidden, похожее на Disabled. Главное различие между ними состоит в том, что при значении Hidden полоса прокрутки хоть и не видна, но содержимое все же прокручивается.

Элемент ScrollViewer поддерживает также горизонтальные полосы прокрутки. Отличие от вертикальных состоит в том, что свойство HorizontalScrollBarVisibility по умолчанию имеет значение Hidden, а не Visible. Чтобы сделать горизонтальную полосу прокрутки видимой, нужно явно установить значение Visible или Auto.

Масштабирование интерфейса

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

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

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

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

Масштабирование элементов

Чтобы получить такой эффект, нужно применить класс преобразований ScaleTransform. Классы преобразований (transforms) — ключевое средство гибкой инфраструктуры двухмерного рисования, встроенной в Silverlight. С их помощью можно изменять масштаб, наклонять и поворачивать любой элемент страницы. В данном примере используется класс ScaleTransform, предназначенный для изменения масштаба страницы.

Существуют два способа использования класса ScaleTransform. В первом способе вы делаете все сами: создаете реакцию на событие UserControl.SizeChanged, проверяете текущий размер страницы, вычисляете новые размеры и создаете объект ScaleTransform. Другой способ намного менее трудоемкий. Вы можете применить элемент управления Viewbox, решающий все указанные задачи без единой строки кода.

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

Ниже приведена разметка контейнера Grid, приведенного на рисунке выше, с начальными размерами 200x225 пикселей, содержащая ряд текстовых полей и кнопок:

<UserControl x:Class="SilverlightTest.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <!-- Этот контейнер необходим для масштабирования -->
    <Viewbox>
        <!-- Этот контейнер является корневым 
             для пользовательского интерфейса; обратите внимание на то,
             что в нем жестко закодированы размеры -->
        <Grid Background="White" Margin="3,3,10,3" Height="225" Width="200">
            <Grid.RowDefinitions>
                <RowDefinition Height="*"></RowDefinition>
                ...
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"></ColumnDefinition>
                <ColumnDefinition Width="Auto"></ColumnDefinition>
            </Grid.ColumnDefinitions>

            <TextBox Grid.Row="0" Grid.Column="0" Margin="3" 
                     Height="Auto" VerticalAlignment="Center" Text="Пример текста"></TextBox>
            <Button Grid.Row="0" Grid.Column="1" Margin="3" Padding="2"
        			 Content="Browse"></Button>

            ...
            
        </Grid>
    </Viewbox>
</UserControl>

В данном примере объект Viewbox сохраняет пропорции масштабируемого содержимого. Иными словами, он масштабирует содержимое таким образом, чтобы вместить его в наименьший размер (ширину или высоту), а не во все пространство. Чтобы объект Viewbox заполнил все пространство, не сохраняя пропорции, присвойте его свойству Stretch значение Fill. Для масштабирования страниц это не очень полезно, однако может пригодиться в других целях, например для масштабирования векторной графики в кнопке.

Важно отметить, что, поместив объект Viewbox в ScroliViewer, можно создать ряд интересных эффектов. Например, можно вручную задать размеры объекта Viewbox (с помощью свойств Height и Width) большими, чем доступное пространство, и прокручивать увеличенное содержимое. Обычно такой метод применяется для создания зуммируемого пользовательского интерфейса, размеры которого изменяются, когда пользователь перетаскивает ползунок или прокручивает колесико мыши.

Полноэкранный режим

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

Ниже перечислены ограничения полноэкранного режима:

Указанные ограничения отменяются при создании приложения с повышенным уровнем привилегий.

Ниже приведен код обработчика, который в ответ на щелчок кнопкой мыши переключает приложение в полноэкранный режим:

private void Button_Click(object sender, RoutedEventArgs e)
{
       Application.Current.Host.Content.IsFullScreen = true;
}

В момент переключения в полноэкранный режим приложение выводит на экран сообщение, показанное на рисунке ниже. Сообщение содержит адрес домена, в котором расположено приложение. При использовании сайта ASP.NET и встроенного веб-сервера Visual Studio выводится адрес http://localhost. Если приложение хостируется тестовой HTML-страницей, хранящейся на жестком диске, выводится адрес file://.

Сообщение, выводимое при переключении в полноэкранный режим

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

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

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

Application.Current.Host.Content.FullScreenOptions =
     System.Windows.Interop.FullScreenOptions.StaysFullScreenWhenUnfocused;

Эта инструкция должна выполняться перед переключением в полноэкранный режим. Позже, при установке свойства IsFullScreen, система попросит пользователя подтвердить разрешение закрепить полноэкранный режим. Если пользователь установит флажок Remember my answer (Запомнить мой ответ), то при следующей попытке переключения в полноэкранный режим данное диалоговое окно не появится:

Закрепление приложения в полноэкранном режиме

Если пользователь подтвердит разрешение, приложение останется закрепленным в полноэкранном режиме, пока пользователь не нажмет клавишу <Esc> или код не присвоит свойству IsFullScreen значение false. Если пользователь не подтвердит разрешение, приложение переключится в полноэкранный режим, но немедленно выйдет из него при потере фокуса.

Пройди тесты
Лучший чат для C# программистов