How to display charms on a top of the WebView.


I’ve been moving along in my development of the FeedPoint app to WinRT. And as a good citizen of the Modern UI I needed to implement app contracts such as search, share and settings which become available for a user via charms. When displaying Accounts flyout in my app I’ve noticed that it doesn’t show properly on the page that’s using the WebView control because the flyout gets hidden behind the WebView:

 

This is happening because of the way the WebView control implemented and its internal drawing logic. This MSDN page suggests to use the WebViewBrush to overcome this issue by placing a rectangle with a snapshot on a top of the WebView. So I did the same. First I placed the Rectangle in my XAML after the WebView. This insures that the Rectangle will be on a top of the WebView: 

<WebView x:Name=”webViewContent”  Grid.Column=”2″ Grid.Row=”1″ Margin=”40,0,10,0″ ScriptNotify=”webViewContent_ScriptNotify”>
            <WebView.RenderTransform>
                <CompositeTransform/>
            </WebView.RenderTransform>
</WebView>      

<Rectangle x:Name=”webViewBrushRect” Visibility=”Collapsed”  Grid.Column=”2″ Grid.Row=”1″ Margin=”40,0,10,0″ />

Next, I’ve added SwitchWebView public method to the code behind of this page:

 public void SwitchWebView(bool back)
 {
     if (!back)
     {
         WebViewBrush brush = new WebViewBrush();
         brush.SourceName = “webViewContent”;
         brush.Redraw();

         webViewContent.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
         webViewBrushRect.Visibility = Windows.UI.Xaml.Visibility.Visible;
         webViewBrushRect.Fill = brush;
    }
    else
    {
         webViewContent.Visibility = Windows.UI.Xaml.Visibility.Visible;
         webViewBrushRect.Fill = new SolidColorBrush(Colors.Transparent);
    }
}

 

 This method creates a new WebViewBrush, assigns the source for it to be the name of the WebView control, changes visibility and assigns the brush to the Rectangle. This method needs to get called when a flyout becomes visible. It could be done in the constructor like this: 

                  public AccountsUserControl()
        {
            this.InitializeComponent();         

            if (App.CurrentFrame != null)
            {
                if (App.CurrentFrame.CurrentSourcePageType.Name == “FeedPage”)
                {
                    var feedPage = (FeedPage)App.CurrentFrame.Content;
                    feedPage.SwitchWebView(false);
                }
            }
        }

        private void OnBackButtonClicked(object sender, RoutedEventArgs e)
        {
            if (this.Parent.GetType() == typeof(Popup))
            {
                ((Popup)this.Parent).IsOpen = false;
                if (App.CurrentFrame != null)
                {
                    if (App.CurrentFrame.CurrentSourcePageType.Name == “FeedPage”)
                    {
                        var feedPage = (FeedPage)App.CurrentFrame.Content;
                        feedPage.SwitchWebView(true);
                    }
                }
            }
            SettingsPane.Show();
        }

 Don’t forget to switch it back when the back button is clicked. Here’s the screenshot of the result:

 

Comments (6)

  1. Jussi Palo says:

    I have IsLightDismissEnabled enabled, so user can close the settings charm by tapping somewhere on the screen and OnBackButtonClicked isn't fired. What would be the correct event handler to catch that tap so that WebView could be reverted back to normal?

    Thanks!

  2. Jussi Palo says:

    I ended up putting the code in the Closed event handler of the Popup that contains my SettingsFlyout.

    Thanks for the instructions though, helped a lot!

  3. Biber says:

    But there is no App.CurrentFrame??? :/

  4. AlexYak says:

    It's just this in the App.xaml.cs:

           public static Frame CurrentFrame

           {

               get

               {

                   return Window.Current.Content as Frame;

               }

           }

  5. Biber says:

    I owe you a chocolate 🙂

    Thank you.

  6. Jason Short says:

    So that means you implement a flyout per PAGE in your app?  Yikes.  30 pages = 30 flyouts?

    I have one global flyout handler that has no knowledge of the page it is on.  That sort of screws this up.  Why can't the ad team just fix this?  I shouldn't have to write crappy hacks because of a scenario bug on their end.  Let them make the screenshot and rectangle change.

Skip to main content