Devlico.Us
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @devlicious

Christopher Bennage

Our WPF book is now available!

July 2008 - Posts

  • Building a WPF Application: Part 1

    I actually meant to say in my last post that I had investigated the API options for FriendFeed and they have a C# wrapper already available here. It's packaged up in a single download with its Python and PHP counterparts.  Unfortunately, it has compilation errors. I fixed the errors and then I let ReSharper (R#) have its way with it [R#: Ctrl+Alt+Shift+F]. Yes, I do understand that the Code Cleanup feature of R# can be a nuclear bomb of churn for diffing your source, but egads I do love it so.

    FriendFeed project in the solution explorerI also broke out the FriendFeed classes into separate files [R#: F6].

    Hmm, I just decided that I'll notate R# and VisualStudio keyboard shortcuts like this [app:shortcut]. Is there already a convention for that out there?

    I also decided to keep the FriendFeed code in a separate assembly. I don't always advocate assembly proliferation, but it made sense in this case. I created a project called FriendFeed and moved all their classes there.  I also preserved their namespace, FriendFeed, as well. (I'm getting tired of typing "FriendFeed".)

    At this point, I just wanted to get a feel for the API. So I read over what appeared to be the significant classes, and I used a couple of tests to see how it really works. Simple enough, instantiate the client and call FetchHomeFeed().

    Building in Seams

    I picked up the term seam from Ayende in this post. You can think of a seam as a natural boundary in an application. It's a place where you easily extend or modify an application. It's a little bit like a Bounded Context, but just a little. I used to try to coerce my design into the metaphor of layers, but seams are a more natural concept. You might also think of them as a way of describing componentized architecture.

    Consider the example of a desktop computer: you have a motherboard, CPU, memory, video card, etc. All of the components are required for the computer to function, but you can replace any one of them. You can extend the functionality of the computer by adding more hardware. Some things might be tightly coupled, like those wretched integrated video cards. But you don't think of these components as layers. This is a flexible way to architect your application.

    Seams are a standard consideration for me when it comes to designing an application. Yes, you can go crazy with it, you can go crazy with anything. In the case of ChumChase, I don't want to be tightly coupled to the official API. I have a few reasons right now: [a] the official API might change. [b] I might want to implement my own API against their web services just for kicks [c] it's a good excuse to demonstrate the technique. I'm going to hide the FriendFeed API behind a repository. The IFeedRepository interface will be a seam in my application.

    MVP

    I mentioned before that I'm going to use Model-View-Presenter. This pattern is similar to MVC, and like barbeque sauce, everyone has their own flavor. In my case, a presenter is a class that represents the behavior of the UI, and possibly some state. It is ignorant of how the UI visually appears. The view will be a user control, window, page, tab item, etc. We'll use data binding to glue the two together. The ignorance of the presenter about the view is important because it helps us to isolate the presenter in our unit tests.

    TDD

    It's sometimes hard to decide where to start writing to tests. I tend to write tests that reflect the behaviors of the user interacting with the application. This is as opposed to testing how the application might interact with a data source, or some other more internal function of the application. This approach of working from the outside in helps prevent me from making too many assumptions about the internals.  The negative is that I have to provide mocks or stubs for the dependencies that I haven't written yet.

    My core story, that is the basic behavior that I'm interested in, is for the application to fetch my home feed. I'll place this feature on a class called HomePresenter. HomePresenter might end up being my only presenter, I don't know yet. It common though for applications to have several presenters. We'll talk later about how to logically organize presenters.

    Let's look at a test:

    [TestFixture]
    public class The_presenter_for_the_home_feed : TestFixtureBase
    {
        private HomePresenter _presenter;
        private IFeedRepository _feedRepository;
    
        protected override void given_the_context_of()
        {
            _feedRepository = Mocks.StrictMock<IFeedRepository>();
            _presenter = new HomePresenter(_feedRepository);
        }
    
        [Test]
        public void can_refresh_the_home_feed()
        {
            using (Record)
            {
                Expect.Call(_feedRepository.FetchHomeFeed())
                    .Return(new List<Entry>());
            }
    
            using (Playback)
            {
                _presenter.RefreshHomeFeed();
            }
        }
    }

    First, my TestFixtureBase is just an abstract class to reduce clutter. The Mocks, Record, and Playback properties all exist on it and they are really just pass-throughs to Rhino.Mocks. Likewise, I have a setup method in TestFixtureBase that calls given_the_context_of() before each test is executed. It's meant to reset the system-under-test (SUT) into a consistent and pristine state.

    Notice that I named my class and method such that they read as a specification for the behavior I'm testing: The presenter for the home feed can refresh the home feed. I'm not sure that I like saying "presenter" in the specification. If I was working with non-technical users, that wouldn't make sense to them. I could replace it with "UI" or "interface" or "screen" perhaps.

    The test has two blocks or phases: record and playback. This is generally a big stumbling block for people. I know when I first encountered it I was thoroughly confused. The record phase is where I tell the test what I'm expecting to happen during the playback phase.  The record phase plays the same roles as asserts.

    The function we are really testing here is:

    _presenter.RefreshHomeFeed();

    Since there is not a state that I can verify after calling RefreshHomeFeed(), I am checking to make sure that it's doing what I expect it to do. That is, I expect it to get a list of entries from a repository of feeds.

    The Expect.Call().Return() is Rhino.Mocks syntax that allows me to say: I expect my SUT to execute _feedRepository.FetchHomeFeed() and I expect that to return a List<Entry> instance. Right now Entry is just an empty class, but conceptually it represents a single item in the feed. You should also note that the relationship between my presenter and the repository is established in given_the_context_of().

    Yes, this is a simple test, but writing this test helped me to shake out what I needed.  Unfortunately, the test as it stands here does not reflect the process of writing it.  I wrote some things, decided they didn't look right, changed them a bit and so on. It probably took me 10 minutes or so before I settled on what you see.

    Moving on to the next test. This is in the same class, so you can read it as: The presenter for the home feed notifies the UI when the home feed is refreshed.

    [Test]
    public void notifies_the_UI_when_the_home_feed_is_refreshed()
    {
        var property_has_changed = false;
    
        _presenter.PropertyChanged +=
            (s, e) => { property_has_changed = (e.PropertyName == "HomeFeed"); };
    
        _presenter.RefreshHomeFeed();
    
        Assert.That(property_has_changed);
    }

    I want to verify that when I call _presenter.RefreshHomeFeed() a change notification is raised for the HomeFeed property. This means my presenter needs a HomeFeed property. I have a boolean flag that helps me track the state and I'm using an inline delegate to set my flag when the property is changed. (There's actually a flaw in this test that we'll examine later, can you see it?) 

    I don't like strings though. If I happen to change the name of the HomeFeed property and forget to change the string in the test, I've broken my test. Of course, I'll notice as soon as I run the tests, but it would sure be nice to eliminate the string. So I wrote this extension method for PropertyChangedEventArgs:

    public static bool HasChanged<T>(this PropertyChangedEventArgs args, Expression<Func<T>> property)
    {
        var expression = (MemberExpression)property.Body;
        return expression.Member.Name == args.PropertyName;
    }

    Now I can change my test to the following and eliminate the string:

    [Test]
    public void notifies_the_UI_when_the_home_feed_is_refreshed()
    {
        var property_has_changed = false;
    
        _presenter.PropertyChanged +=
            (s, e) => { property_has_changed = e.HasChanged(() => _presenter.HomeFeed); };
    
        _presenter.RefreshHomeFeed();
    
        Assert.That(property_has_changed);
    }

    Of course, in between these tests I was writing code to make them pass. (Red -> Green -> Refactor, right?) Here's what my presenter class looked liked afterwards:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq.Expressions;
    using ChumChase.Extensions;
    
    namespace ChumChase.Presenters
    {
        public class HomePresenter : INotifyPropertyChanged
        {
            private readonly IFeedRepository _feedRepository;
            private IList<Entry> _homeFeed;
    
            public HomePresenter(IFeedRepository feedRepository)
            {
                _feedRepository = feedRepository;
            }
    
            public IList<Entry> HomeFeed
            {
                get { return _homeFeed; }
                private set
                {
                    _homeFeed = value;
                    OnPropertyChanged( ()=> HomeFeed);
                }
            }
    
            public void RefreshHomeFeed()
            {
                HomeFeed = _feedRepository.FetchHomeFeed();
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
    
            private void OnPropertyChanged<T>(Expression<Func<T>> property)
            {
                if (PropertyChanged != null) PropertyChanged(this, property.CreateChangeEventArgs());
            }
        }
    }

    The source is now available here. More to come!

    Continue to Part 2.

  • Building a WPF Application: Part 0

    In a rather indirect way, I was inspired by a commenter on one of Scott Hanselman's posts to begin a series that walks through building a WPF application from start to finish. We did this for four different applications in our book, but those where targeted to demonstrate particular facets of WPF whereas in these (yet unwritten) posts I'd like to focus more on "this is how I build my WPF apps". Not to say that my way is the *right way*, but so that we might learn together. In the spirit of the aforementioned post, I'm bound to make mistakes, so please (gently) correct me when you think you see one.

    What to build?

    You might not have noticed, but there's quite a bit of .NET chatter in twit-space. There are already lots of Twitter clients, and some are WPF, so that path has been rigorously trod. However, the technical difficulties surrounding Twitter has given rise to the popularity of another mash up web 2.0 thingy app called FriendFeed.  Everyone seems to agree that the web interface for FriendFeed is all stinky bad, and there's an API readily available, so I think a FriendFeed client is in order.

    ff_logo Briefly, FriendFeed is a way to consolidate all of your creepy Internet voyeurism in one spot. You can track a friend's Flickr account, NetFlix queue, Amazon wishlist, and yes, their Twitter tweets and much, much more. Oh yeah, and you can subscribe to me here. (I'm such a loser.)

    What to do?

    I'm not going to set an agenda or outline a detailed plan. I'm just going to post as I have time to work on it. I started tonight, so I'm expecting to have a real Part 1 posted by midweek. I've already set up a project at CodePlex (though it won't be published for a few more days still.) I named it ChumChase. Isn't that great?

    Part of my plan is to step you through my thinking and decision making process in sort of Nilssonian way. I've only just begun but here's what I can tell you so far.

    • I'm going to use a Model-View-Presenter pattern
    • Expect to see some DDD artifacts.
    • I'm going to use NUnit and RhinoMocks.
    • I'll probably use Windsor too (or maybe StructureMap though, anybody have a preference?)

    I had intended to write a set of user stories  using the issue tracker of CodePlex. However, I got tired of retyping them every time the site errorred out, which was about 60% of the time. (Is that typical for the CodePlex issue tracker? This was my first usage.)  It also occurred to me that I am lazy and ought to have a life outside of coding, so sorry no user stories.

    What to think?

    I'm all about conversation. If this interests you, please let me know. I welcome (friendly) criticisms as well. The more I hear, the more motivated I'll be to do it. (Believe me there's a lot to distract right now. I had a new baby son born on the 10th.)

    Continue to Part 1

  • Using Lambdas to get at properties

    This is a somewhat made-up scenario based on a recent project. My client has not given me permission to discuss the specifics of the application (yet), so I apologize for keeping it vague. I hope you don't give up before the payoff.

    The Problem

    Imagine an application, where a user can create "styles" and those styles can be applied to shapes. The application uses WPF to visualize the shapes with the styles applied.  (Perhaps it's a design tool meant for Hanselman's BabySmash?) Let's say that there are three kinds of shapes: a line, a circle, and a bull's eye.

    styled_shapes Each shape has specific attributes that can be styled, and the these attributes are unique to each shape.  Here's a simple listing of possible attributes:

    Line Circle Bull's Eye

    Stroke

    Fill

    Outer Fill

    Thickness

    Stroke

    Inner Fill

     

    Now, we have three classes to represent the styles: LineStyle, CircleStyle, BullsEyeStyle. The Fill and Stroke attributes are all of type Brush. Furthermore, all three classes derive from ShapeStyle.

    Now, imagine that we have to construct instances of these styles for some data that comes in the form of an API that we don't control. The constructor for LineStyle might look like this:

    public class LineStyle : ShapeStyle
    {
        public LineStyle(ForeignLineStyle style)
        {
            Thickness = style.StrokeThickness;
            Stroke = style.StrokeBrush;
        }
    
        public Brush Stroke { get; set; }
        public double Thickness { get; set; }
    }

    That's simple enough, but remember the properties are of type Brush, and we don't really want our instances of LineStyle to share the same Brush with instances of ForeignLineStyle.  Luckily, Brush has a Clone method! Yeah!  Only, what if the Brush is null? Okay, we'll change it to this:

    public class LineStyle : ShapeStyle
    {
        public LineStyle(ForeignLineStyle style)
        {
            Thickness = style.StrokeThickness;
            Stroke = (style.StrokeBrush != null)
                         ? style.StrokeBrush.Clone()
                         : null;
        }
    
        public Brush Stroke { get; set; }
        public double Thickness { get; set; }
    }

    Now, every time I have a property of type Brush on one of these style classes the pattern is the same.  I  start copying and pasting. (Do you smell something?)  Hmm, what if I have lot of Brush properties? Many more than I initially listed in the table. I sure feel like I am repeating myself.

    At this point, my instinct is to extract this pattern into a method. But how do I do this? The properties are unique to each class, and using reflection would be way overkill.

    Lambda Magic

    What I want is a method that takes the brush from ForeignLineStyle, and the setter for a property of type Brush. Using a lambda for the setter, I am able to create:

    public static void SetBrush(Brush brush, Action<Brush> property)
    {
        var value = (brush != null)
                ? brush.Clone()
                : null;
    
        property.Invoke(value);
    }

    For this to make sense, you need to recognize that a setter is a essentially a method with a signature like this:

    delegate void PropertySetter<T>(T value);

    That signature is the same as Action<T>.

    Now, I can modify LineStyle to look like this:

    public class LineStyle : ShapeStyle
    {
        public LineStyle(ForeignLineStyle style)
        {
            Thickness = style.StrokeThickness;
            SetBrush(style.StrokeBrush, brush => Stroke = brush);
        }
    
        public Brush Stroke { get; set; }
        public double Thickness { get; set; }
    }

    Notice that the second parameter is :

    brush => Stroke = brush

    and not simply

    ()=> Stroke

    The latter is for the getter and would match Func<T>.

    After Thoughts

    Arguably, this doesn't accomplish much.  The repetitive code had a small footprint, and the SetBrush method is likely to throw off other developers.

    It's up to you to decide it's applicability, but a least it's one more tool in the box.

    (Thanks to Rob Eisenberg, who wrote some code that planted this ideas in my head.)

  • TemplateBinding: a bridge between styles and templates

    This is partially a follow-up to my last post contrasting control templates and styles. Like I mentioned before I've been working on an application that has required a custom theme. In addition to styling the standard controls like text boxes and expanders, we've had to create a number of custom controls as well. That has added up to a lot of control templates.

    This recent work has emphasized the importance of the template binding. (Beatriz Costa first helped me get a handle on template binding here.)  TemplateBinding is a special markup extension specifically designed for binding values in a template. (That's a bit of a circular definition, isn't it?) TemplateBinding is the mechanism that allows us to inject values into our templates, or to parameterize them.

    An Example

    First, imagine that we have a resource dictionary where we have defined a set of brushes that we'll use as the palette for our application. We might go about building a control template for the ToolTip control like this:

    <ControlTemplate x:Key="ToolTipTemplate"
                     TargetType="ToolTip">
        <Grid>
            <Border x:Name="DropShadow"
                    Focusable="False"
                    CornerRadius="3"
                    Background="Black"
                    Opacity="0.4"
                    Margin="3 3 0 0" />
            <Border Background="{DynamicResource NormalControlBackground}"
                    BorderBrush="{DynamicResource NormalControlBorder}"
                    BorderThickness="1"
                    Margin="0 0 3 3"
                    CornerRadius="3"
                    Padding="6">
                <ContentPresenter TextBlock.Foreground="{DynamicResource NormalControlText}" />
            </Border>
        </Grid>
    </ControlTemplate>

    This control template is too rigid. What if another team member needs to create a special ToolTip in just one place with a background color other than NormalControlBackground?  They would probably write some markup like this:

    <Button Content="History Eraser Button">
        <Button.ToolTip>
            <ToolTip Background="Red" 
                     Foreground="White"
                     Content="Don't press it!" />
        </Button.ToolTip>
    </Button>

    Sadly, they would discover that it wouldn't work. The control template doesn't know anything about the properties we set on the ToolTip in the markup. Everything is defined in the control template and it's self contained.  We really want the template to be able to use the properties that are set on the control. The template above can be rewritten to do that:

    <ControlTemplate x:Key="ToolTipTemplate"
                     TargetType="ToolTip">
        <Grid>
            <Border x:Name="DropShadow"
                    Focusable="False"
                    CornerRadius="3"
                    Background="Black"
                    Opacity="0.4"
                    Margin="3 3 0 0" />
            <Border Background="{TemplateBinding Background}"
                    BorderBrush="{TemplateBinding BorderBrush}"
                    BorderThickness="{TemplateBinding BorderThickness}"
                    Margin="0 0 3 3"
                    CornerRadius="3"
                    Padding="{TemplateBinding Padding}">
                <ContentPresenter TextBlock.Foreground="{TemplateBinding Foreground}" />
            </Border>
        </Grid>
    </ControlTemplate>

    Using the template bindings allows the control template to pick up the values that are supplied directly on the element, or on the style applied to the element. That means that the Button markup above would work, or we could even create a style for the special case tool tip that looks like this:

    <Style x:Key="WarningStyle" TargetType="ToolTip">
        <Setter Property="Background" Value="Red" />
        <Setter Property="Foreground" Value="White" />
    </Style>

    Handling the Default Values

    If you use a control template with template binding, and don't provide any values on the control, what happens? The default values of the bound properties are used. There are many cases where this is not what you want though. If your intent was to have a global look for tool tips based on our first example, then you want the template to use some specific brushes as well a few other things.

    In this case, you can use a style to set the desired defaults. To apply a style to a control for an entire application, set its TargetType and don't provide a key. The style will also need to be added to (or merged into) the resource dictionary of application. The style is also used to set the custom template for the control (otherwise you'd have to set the Template property on every instance of the control.)

    Here's an example style to accompany our template:

    <Style TargetType="ToolTip">
        <Setter Property="Background" Value="{DynamicResource NormalControlBackground}" />
        <Setter Property="BorderBrush" Value="{DynamicResource NormalControlBorder}" />
        <Setter Property="BorderThickness" Value="1" />
        <Setter Property="Foreground" Value="{DynamicResource NormalControlText}" />
        <Setter Property="Padding" Value="6" />
        <Setter Property="Template" Value="{DynamicResource ToolTipTemplate}" />
    </Style>

    I'm interested in feedback. If you find this useful, or too basic, or whatever, please let me know!

More Posts

Our Sponsors

Red-Gate!