Page view counter

Popup Control

Beta 2 includes a wealth of new controls including the Popup (that is new, right? It’s not that I just didn’t notice it before?).

I received an email today asking if I’d do a short How Do I video on creating a Popup and I certainly will, but here is a wicked fast tutorial for those of you who can’t wait….

There are three approaches.

1. Create the Popup as Xaml, most easily in Blend

2. Create the Popup dynamically, most easily in Visual Studio

3. Create the Popup as a User Control (the right answer, once you’re comfortable with how Popups are created

 

Creating the Popup in Xaml

Here is a picture of what we’re going to build. The basic Silverlight control will have a button and an image…..

PopupNotShowing

The button’s event handler makes the Popup visible.

PopUpShowing

If you are old enough to get the reference, from having watched it when it was first on, remind me to buy you a glass of milk the next time we’re at a conference together

There are two important things to notice:

  • the Popup covers any elements that are at  its location (when you create it you give it a vertical and horizontal offset from the upper left of the control) and
  • the Popup is entirely within the Silverlight control.

Method 1 - Xaml

 

Create your basic project with the Click Me button and the Image in Blend. Set their properties as usual.

ObjectsInBlend

Then select a Popup from the Asset Library

AssetLibrary

and place that inside your Grid as well. Make the Popup the container by double clicking on it, and you are ready to add the border and StackPanel. Double click on the panel to make it  the container and add the TextBlock and Button.  Set all the properties.

Once you have the controls set, it is time to save all the files and edit in Visual Studio.

Your Xaml file will look more or less like this:

<UserControl
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="PopUpControl.Page"
   xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
   mc:Ignorable="d"
    Width="640" Height="480" >

    <Grid x:Name="LayoutRoot" Background="White" >
        <Grid.RowDefinitions>
            <RowDefinition Height="0.15*"/>
            <RowDefinition Height="0.85*"/>
        </Grid.RowDefinitions>
      
        <Button x:Name="ShowPopupButton"
               Height="40" 
              HorizontalAlignment="Left" 
              VerticalAlignment="Bottom" 
              Width="100" 
              FontFamily="Comic Sans MS" 
              FontSize="24" 
              Content="Click me!"/>
        <Image x:Name="LandscapeImage"
             Margin="20,5,50,50" 
             Grid.Row="1"  
             Source="Desert Landscape.jpg" 
             HorizontalAlignment="Left" 
             VerticalAlignment="Top"/>
      
        <Popup x:Name="MyPopup" 
             VerticalOffset="75" 
             HorizontalOffset="25">
         <Border BorderBrush="Black" BorderThickness="5">
               <StackPanel x:Name="PopUpPanel" 
                        Background="#FFB9F4E2"
                        Height="Auto" Width="Auto" >
                   <TextBlock  x:Name="PopUpText"
                  Height="143" Width="Auto" 
                      Text="Danger Will Robinson!!"  
                      FontFamily="Comic Sans MS" FontSize="48" 
                  HorizontalAlignment="Center" VerticalAlignment="Center" 
                  Foreground="#FFD91F1F"/>
                   <Button x:Name="ClosePopup"
                       Height="34" 
                       Width="73" 
                       Content="Close" 
                       Background="#FF86F922" 
                       FontFamily="Verdana" FontSize="14" />
               </StackPanel>
         </Border>
        </Popup>
    </Grid>
</UserControl>

Notice that the Popup has a VerticalOffset and a HorizontalOffset; that positions it with respect to the upper left hand corner of the Silverlight control.

The Code-behind

The Constructor sets up Page_Loaded which in turn sets up the event handlers for the two buttons,

public Page()
{
    // Required to initialize variables
    InitializeComponent();
   Loaded += new RoutedEventHandler( Page_Loaded );
} 

void Page_Loaded( object sender, RoutedEventArgs e )
{
   ShowPopup.Click += new RoutedEventHandler( ShowPopup_Click );
   ClosePopup.Click += new RoutedEventHandler( ClosePopup_Click );
} 

void ClosePopup_Click( object sender, RoutedEventArgs e )
{
   MyPopup.IsOpen = false;
} 

void ShowPopup_Click( object sender, RoutedEventArgs e )
{
   MyPopup.IsOpen = true;
}

Creating the Popup Dynamically

 

An alternative approach is to set up the first button and the image as before, but to create the Popup in code.  In your Xaml file you just eliminate the Popup altogether. No other changes. The big change is in the code-behind:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Controls.Primitives;

namespace PopUpInCode
{
   public partial class Page : UserControl
   {
      private Popup myPopup = new Popup();

      public Page()
      {
         InitializeComponent();
         Loaded += new RoutedEventHandler( Page_Loaded );
      }

      void Page_Loaded( object sender, RoutedEventArgs e )
      {
         ShowPopup.Click += new RoutedEventHandler( ShowPopup_Click );  
      }

      void ShowPopup_Click( object sender, RoutedEventArgs e )
      {


         Border border = new Border();
         border.BorderBrush = new SolidColorBrush( Colors.Black );
         border.BorderThickness = new Thickness( 5.0 );


         StackPanel myStackPanel = new StackPanel();
         myStackPanel.Background = new SolidColorBrush( Colors.LightGray );
         

         TextBlock tb = new TextBlock();
         tb.Text = "Danger Will Robinson!!";
         tb.FontFamily = new FontFamily("Comic Sans MS");
         tb.FontSize = 48.0;
         tb.HorizontalAlignment = HorizontalAlignment.Left;
         tb.VerticalAlignment = VerticalAlignment.Center;
         tb.Foreground = new SolidColorBrush( Colors.Black );


         Button closePopup = new Button();
         closePopup.Content = "Close";
         closePopup.Background = new SolidColorBrush( Colors.Magenta );
         closePopup.FontFamily = new FontFamily( "Verdana" );
         closePopup.FontSize = 14.0;
         closePopup.Width = 50.0;
         closePopup.Click += new RoutedEventHandler(ClosePopup_Click);
         closePopup.Margin = new Thickness( 10 );



         myStackPanel.Children.Add( tb );
         myStackPanel.Children.Add( closePopup );

         border.Child = myStackPanel;

         myPopup.Child = border;

         myPopup.VerticalOffset = 75.0;
         myPopup.HorizontalOffset = 25.0;
         myPopup.IsOpen = true;
      }

      void ClosePopup_Click( object sender, RoutedEventArgs e )
      {
         myPopup.IsOpen = false;
      }
   }
}

You’ll notice that I hewed pretty close in the code to what I had created in the Xaml without making myself too crazy. 

The Third, and Right Way

The right way to do this, now that I’ve shown all that, is to make the Popup as a UserControl, which of course you can create as a separate .xaml file and design beautifully in Blend. then the PopUp has only to contain your UserControl and you are all set.

I’ll show that in the video. (Hey! I need something to add in the video).

Thanks.

-jesse

 

Source code  How to use this source code

Published Friday, June 06, 2008 11:32 AM by jesseliberty
Filed under:

Comments

# re: Popup Control

Popup was already in beta 1.

But it had a bug before. If you click some thing inside the popup to close the popup (we use the popup to make a dropdown combo box), it will crash. We have to use a timer to delay that myPopup.IsOpen call to get around the problem. Seems they fixed it beta 2. Have to try it when installed beta 2.

Friday, June 06, 2008 12:13 PM by sladapter

# re: Popup Control

You said:

"Beta 2 includes a wealth of new controls including the Popup (that is new, right? It’s not that I just didn’t notice it before?)."

I count only one new control, still no ComboBox, TreeView, or Rich Text.

Maybe you were joking, sorry if I missed it.

Friday, June 06, 2008 12:27 PM by samcov

# re: Popup Control

Yeah, popup control was in beta 1.

I hope combo box and rich text box are available by RTM too.

Friday, June 06, 2008 12:55 PM by ccchai

# re: Popup Control

Is there something new in Beta 2 for popup? is there a property to make it "modal"? so you can click anything else until you close it?

Friday, June 06, 2008 2:00 PM by diegolaz

# re: Popup Control

No popup was in beta 1 but since i said i'd only be talking about beta 2 this month, and sine someone asked me to explain how it is used...

That said, there are many new controls (really, you see only 1?)  I'll have to get the list, but my count is that there are a lot more controls in my tool box than there used to be.  

Much more to come on this once we release (RRSN)

Friday, June 06, 2008 2:22 PM by jesseliberty

# re: Popup Control

Hey Jesse, is it possible to create a basic form from a Popup as a User Control and then add content to it either at runtime or at design time?

i.e. I can put the border, stack panel and the close button and create this as a generic SL Form, and then from this point use this form and add other contents to it as a new control?

Even better to take a one step further and create a skin for the form too.

But one step at a time... :-)

..Ben

Friday, June 06, 2008 2:55 PM by BenHayat

# re: Popup Control

No, Popup was not in the toolbox. But it was there. I could type the Tag in the Xaml and I could create it in code. We have been using it all the time.

If you consider the controls that was not in beta1 toolbox are new controls, then maybe there are a lot of new controls.

Friday, June 06, 2008 3:04 PM by sladapter

# re: Popup Control

Where is WatermarkedTextBox?

..Ben

Friday, June 06, 2008 4:09 PM by BenHayat

# re: Popup Control

The only new control I see added, is the Tab Control.

..Ben

Friday, June 06, 2008 4:13 PM by BenHayat

# Silverlight Cream for June 06, 2008 -- # 292

Some reading while waiting for B2--- John Stockton on Intranet Installations, Jesse Liberty on the Popup

Friday, June 06, 2008 6:18 PM by Community Blogs

# re: Popup Control

About partial code...

I uploaded partial code because a user suggested to me that it was painful downlaoding an entire project.

I have now received feedback that my solution is penny wise and pound (dollar?) foolish and I agree. After going through the steps of recreating the project, it is just too painful. So I'll be uploading full projects from now on.

Thanks.

Sunday, June 08, 2008 11:59 AM by jesseliberty

# re: Popup Control

This kind of popups are modal, is it possible to configure them to be modeless?

Nice tutorial, ... I was creating this thing manually :).

Sunday, June 15, 2008 10:39 AM by brauliod

# re: Popup Control

It would be quite interesting to see how to extend the popup control, in order to have a base popup template (e.g. a base popup that has by default certain colors, a close button... so you don't have to repeat that boiler plate code on each popup in your application).

Sunday, June 15, 2008 12:14 PM by brauliod

# re: Popup Control

Jesse,

Is there a way to get the absolute x and y positions of another control on-screen?  It would be useful to be able to dynamically position a popup directly below its calling control.

This would be one way to create a custom combobox control, using popup to display a listbox of data choices.

Tuesday, July 01, 2008 11:39 AM by jregehr

# re: Popup Control

when is the video coming up? Or is it already up? thanks.

Thursday, July 31, 2008 4:18 AM by debbiea

# re: Popup Control

So where the video is?...

Thursday, August 14, 2008 4:11 AM by Gabrielle

# re: Popup Control

If I add an image into Popup it don't show it. Someone can tell me why?

Thursday, November 13, 2008 6:38 AM by ice85

# re: Popup Control

Thanks for the example.

The msdn library entry for popup has a note that the popup should be added to the visual tree to prevent runtime errors.  I have a couple of questions about that:

Is that still necessary as a workaround?  I ask because it isn't shown above.

What do you suggest as best practices for doing this?  The example code suggests "LayoutRoot.Children.Add(myPopup);" but that opens up some issues.  LayoutRoot might not be the name of the top panel, and if you're implementing a user control it isn't in scope anyway.  But you can't always add the popup to the user control because it might have a Border (with one Child rather than Children) as the top level item.

It seems like this complicates the destructor/release step as well - the popup has to be removed from the visual root so it can be garbage collected.

Tuesday, December 09, 2008 11:19 AM by Michaeljz

# re: Popup Control

If you want popups not to crash when you create them in code you need to link them to the parent.  Basically add the new pop to the children.

In the below code TestPopupItem is a standard user control.

Popups.TestPopupItem filterWindow = new Popups.TestPopupItem();

this.filterPopup = new Popup();

this.LayoutRoot.Children.Add(this.filterPopup);

this.filterPopup.HorizontalOffset = 80;

this.filterPopup.VerticalOffset = 80;

this.filterPopup.Child = this.filterWindow;

this.filterPopup.IsOpen = true;

Thursday, January 08, 2009 4:28 PM by John.J.Hughes.II

# re: Popup Control

So...how about that custom popup video? :D

Thursday, January 15, 2009 8:38 AM by 22khz

# re: Popup Control

So you tell us and supply sample code for both "wrong" ways and we get no help doing it the right way?

Where is the sample code?  Where is the video you promised?

Wednesday, January 21, 2009 3:36 PM by mwieder

# re: Popup Control

mWieder, the two ways I showed were not wrong, they just weren't as cool as using a user control (I do have videos on adding user controls; I'll have to check on whether I actually went back and did show the popup as a user control. If not, I'll be sure to add that to the list as you are right, I certainly promised to do so.  

Monday, January 26, 2009 3:57 PM by jesseliberty