WindowlessControls Tutorial Part 2

It's late, and I'm waiting for Mono to finish cross compiling for Android (hopefully with better results), so I figured I'd write up the next part of the WindowlessControls Tutorial series.

Recently, Chris Craft blogged about Alpha Blending in .NET Compact Framework. One of his suggestions was to use the Alpha Mobile Controls. After using and learning that API bit, you will quickly discover that in practice, it is not really usable. When I initially began investigation into Alpha Blending controls, I took the same approach as Alpha Mobile Controls. This design ended up hitting a dead end due to layout issues, and difficulty in actually reusing controls. It made me rethink how to implement a mobile UI framework. The requirements then ballooned and I ended up implementing WindowlessControls.

In In this article, I will demonstrate usage of the following:

  • How to use the WrapPanel, another common layout element. A WrapPanel aligns elements either side by side or top to bottom in a given direction. When it runs out of room in that direction, it will wrap to the next line. This works just like WPF's WrapPanel.
  • How to use the OverlayPanel. The OverlayPanel allows you to layer controls on top of each other.
  • The ImageButton class - A clickable button that displays an image. This image can have alpha.
  • How to enable transparencies in WindowlessControls.

Let's start with these three images:

Wallpaper users tip

The first image will become the background for our form. The next two images will be transparent buttons on that background (the black/gray area is actually transparent, the blog is munging it).

To do this, we will need to create an OverlayPanel. This OverlayPanel will contain two other controls: a background and a foreground. The background will be a WindowlessImage containing the leaf bitmap. The foreground will be a WrapPanel containing the two ImageButtons. Let's see what this looks like in code:

 

public AlphaDemo()
{
    InitializeComponent();

    // we need to layer two controls on top of another: a background, with another panel containing more controls
    StackPanel stack = myHost.Control;
    OverlayPanel overlay = new OverlayPanel();
    stack.Controls.Add(overlay);

    // set up the background bitmap and control
    PlatformBitmap backgroundBitmap = PlatformBitmap.FromResource("Wallpaper.jpg");
    WindowlessImage background = new WindowlessImage(backgroundBitmap);
    background.Stretch = Stretch.Uniform;
    overlay.Controls.Add(background);

    // set up the foreground
    StackPanel foreground = new StackPanel();
    overlay.Controls.Add(foreground);

    // load the transparent images
    PlatformBitmap users = PlatformBitmap.FromResource("users.png");
    PlatformBitmap tip = PlatformBitmap.FromResource("tip.png");

    // the two buttons will be placed in a WrapPanel
    // a wrap panel will horizontally or vertically lay out elements in a given direction until it runs out of room in that direction.
    // when it runs out of room, it will "wrap" to the next line.
    // since this wrap panel is contained in a vertical stack panel, it will lay out elements horizontally, and wrap vertically to the next line.
    WrapPanel wrap = new WrapPanel();
    foreground.Controls.Add(wrap);

    // set up the users button
    ImageButton userButton = new ImageButton(users, Stretch.None);
    // controls must be explicitly marked as being transparent. transparency is disabled by default on controls for performance reasons.
    userButton.BackColor = Color.Transparent;
    wrap.Controls.Add(userButton);
    userButton.WindowlessClick += (s, e) =>
    {
        MessageBox.Show("You just clicked users!");
    };

    // set up a tip button next to the users
    ImageButton tipButton = new ImageButton(tip, Stretch.None);
    tipButton.BackColor = Color.Transparent;
    wrap.Controls.Add(tipButton);
    tipButton.WindowlessClick += (s, e) =>
    {
        MessageBox.Show("You just clicked the tip!");
    };
}

And when you run this code, you see the following buttons which support transparencies. Notice that in the portrait, the second button can't fit on the first line, so it wraps to the next line. But if you rotate the orientation, it no longer needs to wrap, and comes back up to the first line. That's the WrapPanel in action!

image image

Cool huh!? As the code comment says, transparencies are disabled by default. This is because performing alpha computations is very expensive, and should only be used on an as needed basis. Click here for the updated tutorial.

0 comments: