Creating a Pseudo-Dialog with Silverlight's Popup Control

  • May 01, 2008 at 1:03 AM
  • Shawn Wildermuth
  • 8 Comments

Url: http://wildermuth.com/downloads/popupfun.zip

Silverlight Logo

Originally I had planned to start my screencast this week with a how-to on creating a sort of fake dialog window in Silverlight 2. Unfortunately I got the flu so I've decided to put off the screencast for another week but share with you how to create the fake dialog, but in full fidelity text and code examples.  If you cross your eyes, it looks like its even in 3D.

The cornerstone of creating a fake dialog in Silverlight 2 is the Popup control. The Popup control is a special container that when shown always shows up over other controls without taking up any space. For example, here is a simple Silverlight 2 app with a Rectangle and a Button.  In addition, we've added a Popup with a simple Grid inside it:

<UserControl x:Class="PopupFun.Page"
    xmlns="http://schemas.microsoft.com/client/2007" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    >
  <Grid x:Name="LayoutRoot" Background="White">
    <StackPanel Width="200" Height="200" VerticalAlignment="Top">
      <Rectangle Fill="Blue" Width="100" Height="100" />
      <Button x:Name="showButton" Content="Click Me" />
    </StackPanel>
    <Popup x:Name="fakeDialog">
      <Grid x:Name="theBack" Background="#80000000">
        <Grid.RowDefinitions>
          <RowDefinition />
          <RowDefinition Height="Auto" />
          <RowDefinition />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
          <ColumnDefinition />
          <ColumnDefinition Width="Auto" />
          <ColumnDefinition />
        </Grid.ColumnDefinitions>  
        <Border BorderBrush="Black" 
                BorderThickness="2" 
                Background="WhiteSmoke" 
                CornerRadius="15" 
                Grid.Column="1" 
                Grid.Row="1">
          <StackPanel Margin="8" Width="200" >
            <TextBlock TextWrapping="Wrap">
                This is just some sample text. It doesn't 
                matter what it says as long as it is long 
                enough to actually wrap
            </TextBlock>
            <Button x:Name="closeButton" 
                    Content="Close" 
                    VerticalAlignment="Bottom" />
          </StackPanel>
        </Border>
      </Grid>
    </Popup>
  </Grid>
</UserControl>

When we show the page initially, the Popup is hidden (because it's IsOpen property is false by default):

 

But when we change the IsOpen property (in the Click eevent of the Button),. the Popup is shown on top of the existing content:

 

What is particularly interesting about the Popup control is that it takes no space in whatever container it resides in.  The Popup control is meant to shown over the existing content. The problem is that you will want to take over the entire screen with the fake dialog.  In this case the size of the Popup won't cover the entire screen by default.  To fix this we can register for the Application's Resize event to change the size of the Grid (named "theBack") inside our Popup:

App.Current.Host.Content.Resized += (s, e) =>
{
  theBack.Width = App.Current.Host.Content.ActualWidth;
  theBack.Height = App.Current.Host.Content.ActualHeight;
};

This will resize the Grid whether the Popup is shown or now. Now that we have the resizing code in place, the dialog takes over for the entire screen:

 

There are a number of things you can do with a Popup control, but this should give you a quick primer on how the Popup control really works.  The source project can be downloaded at the link above.

 

Comments

Gravatar

Everett Thursday, May 1, 2008

when the fakeDialog is showing, press <Tab> key showbutton can be focused. if you have a textbox, you can input something in it when the fakeDialog is showing. how resolve this issue?:)

Gravatar

timheuer Thursday, May 1, 2008

@everett: as shawn points out this is a pseudo-dialog...not a true dialog, so controls are still there and can have focus/edit since popup control is not a modal control

Gravatar

Shawn Wildermuth Thursday, May 1, 2008

Everett,

Tim is right, its not truly Modal. You could play with the LostFocus event of the button on the Popup but I don't suggest this as its hacky and can have undesireable side effects.

Gravatar

Dominic B. Tuesday, August 12, 2008

Here's how to force the TAB key to stay inside the pseudo-dialog:

1)Move the popup content inside a new UserControl (do not forget the application resize monitoring in the contructor)

2)Use this UserControl inside the PopUp. Name it something like "PopUpUC".

3)To show the dialog:
- fakeDialog.IsOpen=True;
- PopUpUC.Focus();
- PopUPUC.TabNavigation = KeyboardNavigationMode.Cycle;

The TAB key will now cycle inside the popup's UserControl only.

Gravatar

Shawn Wildermuth Wednesday, August 13, 2008

Dominic,

That's great information! Thanks!

Gravatar

Laurent Friday, March 6, 2009

Dominic's solution is working fine :)
I also have added a semi transparent background so it is really modal.

Gravatar

Austin Monday, August 3, 2009

Where do you put the: App.Current.Host.Content.Resized += ... When I put this in the button's click event it didn't work.

Gravatar

Shawn Wildermuth Monday, August 3, 2009

You handle that outside the handler, usually in the constructor of the page/control.


Leave a Comment

*
*
*