Exercise 3: Customizing the Window and enabling Elevated Privileges

Silverlight out of Browser enables you to ask the user to install your application with Elevated Privileges (EP). By running Silverlight in an EP mode you have a number of power pieces of functionality at your fingertips: Clipboard access, relaxed cross domain, direct access to the user folder, COM interop, and custom chrome. This exercise covers how to enable Elevated Privileges and then how to create a custom Chrome (a feature that’s crucial for kiosks or brand driving applications).

  1. To enable Elevated Privileges, bring up the Out-of-Browser Settings dialog (Right click the Silverlight project, click Properties, find the Out-of-Browser Settings button towards the bottom.)
  2. Check the Check box labeled “Require elevated trust when running outside the browser”.

    Figure 1

    Enable Check box

  3. Click OK and run the project. If you get to the Install Prompt and it indicates you already have the application installed, Right click, select Remove this application, then refreshes the page. Click the Install button when prompted. Notice the Install prompt looks different than the previous step. This is asking the user for Elevated Privileges.

    Figure 2

    New Install window

  4. Now that Elevated Privileges are enabled, we can have custom chrome on our window. Go back to the Out-of-Browser Settings dialog box and choose No Border from the drop down list labeled Window Style.

    Figure 3

    Out-of-Browser Settings

  5. Run the project to show the chrome is gone. This is the desired effect; however we don’t have a way to close the window. For now, go back to Visual Studio and stop the debugger.
  6. Open up MainPage.xaml and uncomment lines 210-231. This is the WindowControlsPanel that contains buttons that control our window: always on top, minimize, maximize, and close. Below is the XAML uncommented followed by what you should see in Visual Studio.

    XAML

    <StackPanel x:Name="WindowControlsPanel" Grid.Column="1" HorizontalAlignment="Right" Margin="0,2,4,0" Orientation="Horizontal" VerticalAlignment="Top"> <Button x:Name="OnTopButton" Margin="0,0,1,0" Style="{StaticResource TopButtonStyle}" Width="16" Height="16" ToolTipService.ToolTip="Pin to the topmost window"> <Path Data="F1 M477.23441,395.96191 L473.29312,399.9386 L463.59912, 392.70959 L466.6774,389.59689 C467.56339,388.7099467.67639,387.38589 466.93039,386.63989C466.18439,385.89389464.86139,386.0069463.9744, 386.89389 L450.7294,400.13989C449.84241,401.02591 449.7294,402.34891 450.4754,403.09491C451.22141,403.84091 452.54639,403.72791453.4314, 402.8429L455.93942,400.3111 L463.16742,410.00711 L459.79639,413.3999 C458.9104,414.28589 458.79639,415.60791 459.5434,416.35489C460.29041, 417.10089 461.6134,416.98691 462.49939,416.10089L469.23541,409.36591 L480.4234,420.55591 C481.17041,421.2999482.49341,421.18689483.3804, 420.30191 C484.26541,419.41489484.37939,418.09091 483.63339,417.34491 L472.4444,406.15689L479.9364,398.66489 C480.82339,397.77789 480.9364, 396.45389480.18939,395.70789 C479.4444,394.96191 478.1214,395.07489 477.23441,395.96191"Fill="White"Stretch="Fill"UseLayoutRounding="False" d:LayoutOverrides="GridBox" RenderTransformOrigin="0.5,0.5" Margin="1,0,1,2"> <Path.RenderTransform> <CompositeTransform Rotation="45" TranslateY="1.8068817553285044E-09"/> </Path.RenderTransform> </Path> </Button> <Button x:Name="MinimizeButton" Width="16" Height="16" Margin="0,0,1,0" Style="{StaticResource TopButtonStyle}" ToolTipService.ToolTip="Minimize" Padding="0"> <Path Data="F1M229.417,216.229L208.354,237.292C207.544,238.103,207.544,239.416,208.3 54,240.227C209.165,241.037,210.479,241.037,211.289,240.227L232.352, 219.165C233.162,218.354,233.162,217.04,232.352,216.229C231.541,215.419, 230.227,215.419,229.417,216.229"Fill="White" Stretch="Fill" UseLayoutRounding="False" RenderTransformOrigin="0.5,0.5" Height="6" Width="6" Margin="0,6,0,0"> <Path.RenderTransform> <CompositeTransform Rotation="45"/> </Path.RenderTransform> </Path> </Button> <Button x:Name="MaximizeButton" Width="16" Height="16" Margin="0,0,1,0" Style="{StaticResource TopButtonStyle}"ToolTipService.ToolTip="Maximize"> <Path Data="F1M74.313,328.7861C74.313,329.5261,73.713,330.1281,72.973,330.1281L53.03 3,330.1281C52.292,330.1281,51.692,329.5261,51.692,328.7861L51.692, 308.4751C51.692,307.7351,52.292,307.1361,53.033,307.1361L72.973, 307.1361C73.713,307.1361, 74.313,307.7351,74.313,308.4751zM74.806, 305.0221L51.199,305.0221C50.323,305.0221,49.612,305.7311,49.612, 306.6081L49.612,330.6551C49.612,331.5321,50.323,332.2411,51.199, 332.2411L74.806,332.2411C75.683,332.2411,76.393,331.5321, 76.393,330.6551L76.393,306.6081C76.393,305.7311,75.683,305.0221, 74.806,305.0221" Fill="White" Stretch="Fill"UseLayoutRounding="False"/> </Button> <Button x:Name="CloseButton" Width="16" Height="16" Margin="0" Style="{StaticResource TopButtonStyle}" ToolTipService.ToolTip="Close"> <Path Data="M0.54881889,0 C0.68929577,0 0.82977271,0.053546324 0.93699646,0.16063902 L3.3335769,2.5573325 L5.730268,0.1606418 C5.9444532,0.053543516 6.2919092,-0.053543516 6.506361,0.1606418 C6.7205462,0.37508935 6.7205462,0.72254932 6.506361,0.93699688 L4.1097264,3.3335183 L6.5063634,5.730268 C6.7205486,5.9444532 6.7205486,6.291913 6.5063634,6.5063605 C6.2919116,6.7205458 5.9447179,6.7205458 5.7302704,6.5063605 L3.3335588,4.1096492 L0.93673187,6.5063634 C0.72254658,6.7205486 0.37508655,6.7205486 0.16063894,6.5063634 C-0.053546317,6.2919121 -0.053546317,5.9447184 0.16063894,5.7302704 L2.5574095,3.3334999 L0.16064122,0.93673182 C 0.053544026,0.72254652 –0.053544026,0.3750906 0.16064122,0.16063902 C0.26786506,0.053546324 0.40834194,0 0.54881889,0 z" Fill="White" Stretch="Fill" UseLayoutRounding="False" Margin="2" /> </Button> </StackPanel>

    Figure 4

    WindowControlsPanel

  7. We now need to add functionality to each button. The four buttons are pin to top, minimize, maximize, and close. We’ll walk through each event handler, but first we need to register the Click events for each button. Do this in the constructor of MainPage.

    C#

    public MainPage() { InitializeComponent(); // Register Click events for the buttons in the WindowControlsPanel this.OnTopButton.Click += new RoutedEventHandler(OnTopButton_Click); this.MinimizeButton.Click += new RoutedEventHandler(MinimizeButton_Click); this.MaximizeButton.Click += new RoutedEventHandler(MaximizeButton_Click); this.CloseButton.Click += new RoutedEventHandler(CloseButton_Click); } //Pin to Top – Setting the value of Application.Current.MainWindow.TopMost enables //you to pin your application on top of every other app. void OnTopButton_Click(object sender, RoutedEventArgs e) { // Toggle between being on top and not Application.Current.MainWindow.TopMost = !Application.Current.MainWindow.TopMost; } //Minimize – To minimize an out of browser application set the value of //Application.Current.MainWindow.WindowState to WindowState.Minimized. void MinimizeButton_Click(object sender, RoutedEventArgs e) { // Minimize the application Application.Current.MainWindow.WindowState = WindowState.Minimized; } //Maximize– To maximize the window, set the value of //Application.Current.MainWindow.WindowState to WindowState.Maximized. In this event //handler we’re toggling between the Normal WindowState and Maximized. void MaximizeButton_Click(object sender, RoutedEventArgs e) { // Toggle between the Normal and Maximized state if (Application.Current.MainWindow.WindowState != WindowState.Maximized) { Application.Current.MainWindow.WindowState = WindowState.Maximized; } else { Application.Current.MainWindow.WindowState = WindowState.Normal; } } //Close – To close, simply call the Close method of Application.Current.MainWindow. void CloseButton_Click(object sender, RoutedEventArgs e) { // Close the application Application.Current.MainWindow.Close(); }

    Visual Basic

    Partial Public Class MainPage Inherits UserControl Public Sub New() InitializeComponent() ' Register Click events for the buttons in the WindowControlsPanel AddHandler OnTopButton.Click, AddressOf OnTopButton_Click AddHandler MinimizeButton.Click, AddressOf MinimizeButton_Click AddHandler MaximizeButton.Click, AddressOf MaximizeButton_Click AddHandler CloseButton.Click, AddressOf CloseButton_Click End Sub Private Sub OnTopButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs) ' Toggle between being on top and not Application.Current.MainWindow.TopMost = Not Application.Current.MainWindow.TopMost End Sub Private Sub MinimizeButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs) ' Minimize the application Application.Current.MainWindow.WindowState = WindowState.Minimized End Sub Private Sub MaximizeButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs) ' Toggle between the Normal and Maximized state If Application.Current.MainWindow.WindowState <> WindowState.Maximized Then Application.Current.MainWindow.WindowState = WindowState.Maximized Else Application.Current.MainWindow.WindowState = WindowState.Normal End If End Sub Private Sub CloseButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)' Close the application Application.Current.MainWindow.Close() End Sub End Class
  8. Now run you application. Make sure to run it out of the browser (either set the Silverlight project to the Startup project or by reinstalling it). You have now regained control of the Window.

    Figure 5

    Running application