March 2010 - Posts

WPF Routed Events – Bubbling Several Layers Up

Recently, the WPF question of the day for me was how to bubble up a toggle button event through several layers with less code.  In WPF we can easily add layers without worrying about wiring up delegates for each level.

Most of the blogs and MSDN help pages were detailed but not obvious.  This simple example shows how a registered event in the lowest level user control can bubble up for a top level parent to handle the event.  The example bubbles up an event from the QueueButton user control (Level 4) to View2 (Level 3) , then View1 (Level 2), then the top parent Window1 (Level 1) .  There is no code behind nor any delegates to maintain at any level except the firing control and any listeners.  We should be able to add any number of views in the visual tree and still avoid any extra work.  The event is a Bubble event and not Tunnel, but that is an example for another day.  Tunneling can be thought of (informally) as a falling bubble from the top level of the visible tree to the source.  This lets each level receive the event like bubble up does, but knowing that the parent control had an option of acting on the event.

I hope this simple example helps someone keep the WPF code clean and simple.

-Vince

Window1 - Level 1 - The Top Level Listener:

XAML:

<Window x:Class="Routed.Window1"
    xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation
    xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml
    Title="ToggleButton Event Bubbling Example" 
    xmlns:local="clr-namespace:Routed" 
    local:QueueButton.EnableQueue="Window_EnableQueue">
    <Grid>
        <StackPanel>
            <TextBlock Text="Window1" HorizontalAlignment="Center" />
            <TextBlock x:Name="ToggleStateTextBlock" HorizontalAlignment="Center" Margin="10" FontSize="14" />
            <local:View1 />
        </StackPanel>
    </Grid>
</
Window>

 

The Single Code-Behind Method:

private void Window_EnableQueue(object sender, RoutedEventArgs e)
{
    QueueButton queueButton = e.OriginalSource as QueueButton;
    if (null != queueButton)
        ToggleStateTextBlock.Text =
"Toggle Button IsChecked = " + queueButton.IsChecked.Value.ToString();
}

 

View1 - Level 2:  (No Code Behind in View1)

<UserControl x:Class="Routed.View1"
    xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation
    xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml
    Height="200" Width="200"
    Background="Peru"
    xmlns:local="clr-namespace:Routed">
    <Grid>
        <TextBlock Text="View1" HorizontalAlignment="Center" />
        <local:View2 />
        </Grid>
</
UserControl>

 

View2 - Level 3: (No Code Behind in View2)

<UserControl x:Class="Routed.View2"
    xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation
    xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml
    Height="150" Width="150"
    Background="ForestGreen"
    xmlns:local="clr-namespace:Routed">
    <Grid>
        <TextBlock Text="View2" HorizontalAlignment="Center" />
        <local:QueueButton />
    </Grid>
</
UserControl>

 

QueueButton - Level 4 - The Event Source

QueueButton XAML:

<ToggleButton x:Class="Routed.QueueButton"
    xmlns
=http://schemas.microsoft.com/winfx/2006/xaml/presentation
    xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml
    Height="60" Width="100">
    <Grid
>
        <TextBlock Text
="Toggle This!!!" />
    </Grid
>
</
ToggleButton>

 

QueueButton Code Behind:

using System.Windows;
using System.Windows.Controls.Primitives;
namespace Routed
{
        public partial class QueueButton : ToggleButton
        {
            public static readonly RoutedEvent EnableQueueEvent;

            static QueueButton()
            {
                QueueButton.EnableQueueEvent = EventManager.RegisterRoutedEvent("EnableQueue"
                RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(QueueButton));
            }

            public event RoutedEventHandler EnableQueue
            {
                add { AddHandler(QueueButton.EnableQueueEvent, value); }
                remove { RemoveHandler(QueueButton.EnableQueueEvent, value); }
            }

            public QueueButton()
            {
                InitializeComponent();
            }
            protected override void OnChecked(RoutedEventArgs e)
            {
                RaiseEvent(
new RoutedEventArgs(QueueButton.EnableQueueEvent, this));
            }

            protected override void OnUnchecked(RoutedEventArgs e)
            {
               RaiseEvent(
new RoutedEventArgs(QueueButton.EnableQueueEvent, this));
            }
        }
}

 

Posted by vblasberg with no comments
Filed under: ,

DallasXAML.com – A New User Group for Silverlight, WPF, XBAP, etc.

 

The Dallas XAML User Group               

               http://DallasXAML.com

 

I’ve devoted much of last month to starting the DallasXAML User Group.  I finally got back into user group management after 2 years away from leading the Dallas C# SIG.  Now I’m having fun getting a Silverlight/WPF user group going strong for the Dallas / Ft. Worth community.  Our first meeting was March 3rd at the Improving Enterprises offices in North Dallas.  We had about 25 to 35 attendees in the first meeting and it went well.  We covered the most important topic that everyone should understand well – data binding.

 

So I chose the XAML user group so we can get together for a common group improvement in the Dallas / Ft. Worth area and learn cross-technology information that we can use now.  It is not a lecture hall.  The great thing is that we’ll provide hands-on experience with most every meeting.  The goal is to get the experience that we can use the next work day.  I unfortunately broke that rule by speaking all through the first meeting, but next month is part two with more hands-on data binding.

 

The differentiation is this group concentrates on XAML, not Silverlight or Windows Client alone.  What we learn in one area, we gain for all areas.  That includes the Silverlight for Windows Phone 7 coming later this year.  Next year it may be Windows Phone 8, 9, or whatever. 

 

I started developing WPF seriously almost a year ago.  I experienced the painful learning curve.  Anyone who reports that there isn’t a big learning curve either thinks in XAML before it was developed, is on the Silverlight or WPF development team, or has already conquered the learning and forgot the pain.  So I wanted to share the pain or make it easier for others – same thing.  I have found that the more I learn and use good disciplined techniques, the more interesting and rewarding development is again.

 

A few months ago, I was sitting in the iPhone development session at the Dallas C# SIG.  After the meeting, the audience was polled for future topics.  After a few suggestions, Silverlight got the big hands up.  That makes sense because it’s still the hot topic for many Microsoft developers.  So I surfed around and found that there aren’t enough user groups to help in this area.  I polled a few local group leaders and did the work to start the group.  This week I got a telerik controls licence and improved the site with some great controls, namely the RadHtmlPlaceholder control.  It provides a Silverlight control to show HTML in an IFrame-like area.  On DallasXAML.com, the newsletters and resource pages display in HTML because Silverlight just isn’t there yet.  I’m looking forward to a Silverlight XPS viewer with flow documents.  There are some good commercial version available, but this is a non-profit group. 

 

The DallasXAML.com site points to many other resources such as podcasts and webcasts.  I would rather give them the credit than try to out-do them.  So check out the DallasXAML user group site and attend our meetings if you can.  We meet the first Tuesday of the month.

 

-Vince

DallasXAML User Group Leader

 

Good Times on the New Contract

Just a note to the blog to say that my current contract has been going well.  I'm working on contract direct from with own company, FreshMetrics, LLC.  I get to have lunch with Rob Vetter (C# MVP) from next door.  We get to catch up on user group stuff more often now.  The work is great and the team is very serious about the art of software.  It's much more silo'd and quiet than what I'm used to, but that can be a good thing.  I've been heads down with systems analysis, user interviews, and plenty of documentation before building the final application.  It's refreshing to actually have the license to discover instead of hack and go, then wonder when unit tests come into the picture if at all.  I've been pushing myself to do things right with analysis, peer review, and now I'm almost done with unit testing.  Yes - true TDD.  It's been hard not hitting the WPF and WCF services first, but the application is much better already.

The users of this application are asking for features that are easily created in a WPF - click once application.  So I finally started the DallasXAML User Group this week and it's helped at work so far for the WPF portion and the work has helped with the Silverlight User Group site that I created and deployed.  But that's the next blog entry...

 

Posted by vblasberg with no comments
Filed under:
More Posts