Frequently when I see a new technology presented, there are often demos of key concepts that stick in my mind. These examples become things that I feel I must try to build and thoroughly understand myself. At Microsoft's Tech Ed conference in Boston back in June, one of the demos that really stuck with me was the "Kayakalon" demo application used in presentations by Robert Ingebretsen and Lauren Lavoie from the WPF team.
The demo application touched on a number of items revolving around the graphical display of airline flight searches returned from a kayak.com web service. The end result would display flight legs on a graphical time line.
The creation of this TimeLinePanel become a task on the learning list to help me understand. I began trying to recreate the functionality of the control. I started off by inheriting from a Panel control to build a custom panel that would horizontally position child elements based on date criteria.
public class TimeLinePanel : Panel
protected override System.Windows.Size ArrangeOverride(System.Windows.Size finalSize)
protected override System.Windows.Size MeasureOverride(System.Windows.Size availableSize)
In order to handle the layout as required, we are able to override the ArrangeOverride and MeasureOverride methods. The MeasureOverride measures the size in layout required for child elements and determines a size for the element. The ArrangeOverride positions child elements and determines their size. What I wanted to do was to horizontally position the elements based two dates, the would become the start and stop dates for each object, or in the case of the above example the departure and arrival times of the flight legs. In order to take advantage of a WPF design, enabling me to put any type of child elements into this panel, I needed some way to attached these properties to any objects residing in this container, even if they had not concept of these dates.
In .Net 3.0, Microsoft introduces the concept of a DependencyProperty according to the docs "Represents properties that are registered with the Windows Presentation Foundation dependency property system. Dependency properties provide support for value expressions, property invalidation and dependent-value coercion, default values, inheritance, data binding, animation, property change notification, and styling. This class cannot be inherited."
More specifically, I want to make use of an attached property which is "A dependency property that can be attached to any DependencyObject type and that is not limited to the type which defines it. The attached property provider must provide a static get(PropertyName) and set(PropertyName) methods as accessors for these attached properties." So basically, in the end I can create a two properties, independent of their actual types, allowing me to define a start and end date that get attached to any child elements with default values, that can be changed. Through these I can control the layout of the controls.
public static DependencyProperty EventDateProperty;
public static DependencyProperty EventDateRangeProperty;
FrameworkPropertyMetadata metadata = new FrameworkPropertyMetadata(DateTime.Parse("1/1/0001"), FrameworkPropertyMetadataOptions.Inherits );
FrameworkPropertyMetadata metadataB = new FrameworkPropertyMetadata(DateTime.Parse("1/1/0001"), FrameworkPropertyMetadataOptions.Inherits);
EventDateProperty = DependencyProperty.RegisterAttached("EventDate",
EventDateRangeProperty = DependencyProperty.RegisterAttached("EventDateRange",
typeof(DateTime), typeof(Control), metadataB);
public static void SetEventDate(DependencyObject dependencyObject, DateTime eventdate)
public static void SetEventDateRange(DependencyObject dependencyObject, DateTime eventdaterange)
Once these properties are in place, I can define my elements like this:
Windows NT 3.51
Windows NT 4
The end result renders like this:
Working through this example I discovered a lot of cool things that I could easily do to add functionality to this control. The main take away is how you can control how child elements are arranged.
Posted in wpf |