Настройка разрешений

117

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

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

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

Прежде чем приступить к разработке приложения Silverlight с повышенной доверительностью, проанализируйте, не подойдет ли для решения данной задачи полнофункциональное настольное приложение WPF. Платформа WPF полностью поддерживает инфраструктуру .NET Framework. Как и в Silverlight, приложения WPF можно устанавливать из Интернета, но, в отличие от Silverlight, приложения WPF работают только в приложениях Windows.

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

Чтобы указать, что приложение должно требовать повышенной доверительности, откройте окно Out-of-Browser Settings и установите флажок Require elevated trust (Требует повышенной доверительности):

Включение повышенной доверительности

Для запуска процесса установки откройте контекстное меню Silverlight или вызовите метод Application.Install(). На экране появится окно с сообщением системы безопасности. Щелкните на кнопке Установить.

Можете подписать приложение цифровым сертификатом X.509. Тогда в окне системы безопасности предупреждение будет менее грозным, восклицательный знак будет заменен вопросительным и будет отображено имя издателя.

Возможности приложений с повышенной доверительностью

Что может приложение с повышенной доверительностью делать такое, что не по силам обычному приложению Silverlight? Давайте рассмотрим подробнее:

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

Настройка окна

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

Настройка фрейма окна выполняется в два этапа. Первый — полное удаление стандартного фрейма. Для этого в проводнике решений дважды щелкните на узле Properties (Свойства). Откройте вкладку Silverlight и щелкните на кнопке Out-of-Browser Settings (Параметры приложений вне браузера). Выберите один из пунктов списка Window Style (Стиль окна).

Если выбрать значение Default, отобразится стандартный фрейм окна. При выборе второго значения, No Border, будет удален стандартный фрейм окна и оставлен стандартный плавающий прямоугольник с содержимым пользовательского элемента управления. При значении Borderless Round Corners будет удален стандартный фрейм окна и скруглены углы окна приложения. Разница между вторым и третьим вариантами чисто "косметическая", в любом из этих случаев стандартный фрейм окна удаляется. На рисунке ниже показан пример:

Окно Silverlight без рамки

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

Например, можно поместить основное содержимое в одноячеечный контейнер Grid и наложить на него другой элемент Silverlight (Rectangle или Image). Можно также заключить в оболочку Border корневой пользовательский элемент управления следующим образом:

<Border x:Name="windowFrame" BorderBrush="LimeGreen" BorderThickness="5" CornerRadius="2" Margin="0,0,1,1">
        <Grid x:Name="LayoutRoot" Background="#555">
            <TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White" FontSize="16"
                   Text="Окно без рамки"/>
        </Grid>
</Border>

В данном примере в параметрах проекта установлено значение Borderless Round Corners. Внешнее поле (Margin) шириной 1 пиксель справа и снизу обеспечивает вывод фрейма в правильной позиции. Значение CornerRadius, равное 2, выравнивает угол с областью окна:

Безрамковое окно, в котором используется элемент Border

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

Конечно, добавление рамки Border улучшает внешний вид окна, но остается одна важная проблема. Без фрейма, предоставленного операционной системой, пользователь не может изменить размеры окна, переместить его, свернуть, развернуть или закрыть. Если нужно, чтобы пользователь имел возможность выполнять эти операции, нужно запрограммировать их в коде настройки главного окна. К счастью, средства, встроенные в класс Window, существенно облегчают эту задачу.

Первый этап — создание строки заголовка окна. Строка заголовка играет три роли: содержит текст заголовка, служит местом, уцепившись за которое пользователь может перетаскивать окно, и, наконец, содержит кнопки свертывания, развертывания и закрытия окна. В приведенном ниже примере разметка создает базовую строку заголовка. Фигуры кнопок свертывания, развертывания и закрытия прорисовываются с помощью элементов Path и Rectangle.

Второй этап - добавление способа изменения размеров окна путем перетаскивания его краев. Легче всего реализовать его, заключив все окно в оболочку контейнера Grid, в котором используется невидимый элемент Rectangle. Вам понадобятся восемь элементов Rectangle: по одному на каждую сторону и на каждый угол:

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

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

<UserControl x:Class="Silverlight.CustomWindow"
    ...>

    <Border Background="#AAA" CornerRadius="2" Margin="0,0,1,1"
            x:Name="windowBorder">
        <Grid x:Name="resizeContainer">
            <!-- Отступы по 5 пикселей для добавления прозрачных прямоугольников -->
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="5"></ColumnDefinition>
                <ColumnDefinition Width="*"></ColumnDefinition>
                <ColumnDefinition Width="5"></ColumnDefinition>
            </Grid.ColumnDefinitions>

            <Grid.RowDefinitions>
                <RowDefinition Height="5"></RowDefinition>
                <RowDefinition Height="*"></RowDefinition>
                <RowDefinition Height="5"></RowDefinition>
            </Grid.RowDefinitions>

            <!-- Прямоугольники (имитирующие контуры окна) 
                 для изменения размеров окна -->
            <Rectangle x:Name="rect_TopLeftCorner" Grid.Row="0" Grid.Column="0" 
                       Cursor="SizeNWSE" Fill="Transparent" MouseLeftButtonDown="rect_Resize" />
            <Rectangle x:Name="rect_TopEdge" Grid.Row="0" Grid.Column="1"
                       Cursor="SizeNS" Fill="Transparent" MouseLeftButtonDown="rect_Resize" />
            <Rectangle x:Name="rect_TopRightCorner" Grid.Row="0" Grid.Column="2"
                       Cursor="SizeNESW" Fill="Transparent" MouseLeftButtonDown="rect_Resize" />
            <Rectangle x:Name="rect_LeftEdge" Grid.Row="1" Grid.Column="0"
                       Cursor="SizeWE" Fill="Transparent" MouseLeftButtonDown="rect_Resize" />
            <Rectangle x:Name="rect_RightEdge" Grid.Row="1" Grid.Column="2"
                       Cursor="SizeWE" Fill="Transparent" MouseLeftButtonDown="rect_Resize" />
            <Rectangle x:Name="rect_BottomLeftCorner" Grid.Row="2" Grid.Column="0"
                       Cursor="SizeNESW" Fill="Transparent" MouseLeftButtonDown="rect_Resize" />
            <Rectangle x:Name="rect_BottomEdge" Grid.Row="2" Grid.Column="1"
                       Cursor="SizeNS" Fill="Transparent" MouseLeftButtonDown="rect_Resize" />
            <Rectangle x:Name="rect_BottomRightCorner" Grid.Row="2" Grid.Column="2"
                       Cursor="SizeNWSE" Fill="Transparent" MouseLeftButtonDown="rect_Resize" />

            <!-- Содержимое окна -->
            <Grid Grid.Row="1" Grid.Column="1" Background="#555">
                <Grid.RowDefinitions>
                    <RowDefinition Height="28"></RowDefinition>
                    <RowDefinition></RowDefinition>
                </Grid.RowDefinitions>

                <!-- Заголовок окна с кнопками-->
                <Border Background="#222" MouseLeftButtonDown="titleBar_MouseLeftButtonDown" x:Name="titleBar">
                    <Grid>
                        <Grid.Resources>
                            <Style TargetType="Button">
                                <Setter Property="Width" Value="20"/>
                                <Setter Property="Height" Value="20"/>
                                <Setter Property="Margin" Value="0,0,3,0"/>
                                <Setter Property="VerticalAlignment" Value="Center"/>
                                <Setter Property="Template">
                                    <Setter.Value>
                                        <ControlTemplate TargetType="Button">
                                            <Grid Background="Transparent">
                                                <ContentPresenter />
                                            </Grid>
                                        </ControlTemplate>
                                    </Setter.Value>
                                </Setter>
                            </Style>
                        </Grid.Resources>
                        
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition></ColumnDefinition>
                            <ColumnDefinition Width="Auto"></ColumnDefinition>
                            <ColumnDefinition Width="Auto"></ColumnDefinition>
                            <ColumnDefinition Width="Auto"></ColumnDefinition>
                        </Grid.ColumnDefinitions>

                        <TextBlock Margin="5" Foreground="White">Текст заголовка</TextBlock>
                        <Button Grid.Column="1" x:Name="cmdMinimize" Click="cmdMinimize_Click">
                            <Path Stroke="White" StrokeThickness="2" Data="M 1,14 L 13,14"/>
                        </Button>

                        <Button Grid.Column="2" x:Name="cmdMaximize" Click="cmdMaximize_Click">
                            <Rectangle Stroke="White" StrokeThickness="2" Height="12" Width="12"/>
                        </Button>

                        <Button Grid.Column="3" x:Name="cmdClose" Click="cmdClose_Click">
                            <Path Stroke="White" StrokeThickness="2" Data="M 2,2 L 14,14 M 14,2 L 2,14"/>
                        </Button>
                    </Grid>
                </Border>

                <!-- Контент  -->
                <Grid x:Name="LayoutRoot" Margin="5" Grid.Row="1">
                    <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" TextWrapping="Wrap"
                           FontSize="16" FontWeight="Bold" Foreground="White">Содержимое видоизмененного окна.</TextBlock>
                </Grid>
            </Grid>
        </Grid>

    </Border>
</UserControl>
public partial class CustomWindow : UserControl
{
        public CustomWindow()
        {
            InitializeComponent();
        }

        // Ссылка на окно
        private Window CurrentWindow
        {
            get { return Application.Current.MainWindow; }
        }

        // Перетаскивание окна
        private void titleBar_MouseLeftButtonDown(object sender,
          System.Windows.Input.MouseButtonEventArgs e)
        {
            CurrentWindow.DragMove();
        }

        // Изменение размеров окна с помощью кнопок
        private void cmdMinimize_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            CurrentWindow.WindowState = WindowState.Minimized;
        }

        private void cmdMaximize_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            if (CurrentWindow.WindowState == WindowState.Normal)
            {
                CurrentWindow.WindowState = WindowState.Maximized;
            }
            else
            {
                CurrentWindow.WindowState = WindowState.Normal;
            }
        }

        // Закрытие окна
        private void cmdClose_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            CurrentWindow.Close();
        }

        // Изменение размеров окна с помощью курсора мыши
        private void rect_Resize(System.Object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (sender == rect_TopLeftCorner)
            {
                CurrentWindow.DragResize(WindowResizeEdge.TopLeft);
            }
            else if (sender == rect_TopEdge)
            {
                CurrentWindow.DragResize(WindowResizeEdge.Top);
            }
            else if (sender == rect_TopRightCorner)
            {
                CurrentWindow.DragResize(WindowResizeEdge.TopRight);
            }
            else if (sender == rect_LeftEdge)
            {
                CurrentWindow.DragResize(WindowResizeEdge.Left);
            }
            else if (sender == rect_RightEdge)
            {
                CurrentWindow.DragResize(WindowResizeEdge.Right);
            }
            else if (sender == rect_BottomLeftCorner)
            {
                CurrentWindow.DragResize(WindowResizeEdge.BottomLeft);
            }
            else if (sender == rect_BottomEdge)
            {
                CurrentWindow.DragResize(WindowResizeEdge.Bottom);
            }
            else if (sender == rect_BottomRightCorner)
            {
                CurrentWindow.DragResize(WindowResizeEdge.BottomRight);
            }
        }
}

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

Пользовательское окно Silverlight
CodeChick.io - Задачи по программированию с автоматической проверкой
Пройди тесты
Лучший чат для C# программистов