# Thursday, January 22, 2009
Yesterday I posted a bit about a dynamic survey in Silverlight, and today I wanted to start delving into a few details.  First of all, databinding to a user control…

I wanted my datagrid to show a series of radio buttons representing a “rating” from 1-5, where that rating corresponds to an enum value in C# and an integer in SQL. 


For databinding to work the way I’d want, I need to bind the one value in the source to the set of radio buttons in the target.  The easiest way I could think of (and there may be a better way I haven’t thought of) was to make the radio buttons into a user control, and expose a single value.  In the XAML for the datagrid, it looks like



        <t:Rating UserRating="{Binding Path=Answer, Mode=TwoWay}" />



The CellTemplate contains just the user control, and binds its UserRating property to the Answer property in the source.

The XAML for the UserControl is simple

<UserControl x:Class="Evaluation.Rating"


   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >

    <StackPanel Orientation="Horizontal">

        <RadioButton Content="Excellent (5)" x:Name="excellent" Checked="excellent_Checked"/>

        <RadioButton Content="Good" x:Name="good" Checked="good_Checked"/>

        <RadioButton Content="Neutral" x:Name="neutral" Checked="neutral_Checked"/>

        <RadioButton Content="Adequate" x:Name="adequate" Checked="adequate_Checked"/>

        <RadioButton Content="Poor (1)" x:Name="poor" Checked="poor_Checked"/>



In order to get two-way databinding notifications to work properly both ways, the UserRating property of the control is implemented as a DependencyProperty…

public ScaledAnswer UserRating


    get { return (ScaledAnswer)GetValue(UserRatingProperty); }

    set { SetValue(UserRatingProperty, value); }



// Using a DependencyProperty as the backing store for UserRating.  This enables animation, styling, binding, etc...

public static readonly DependencyProperty UserRatingProperty =

    DependencyProperty.Register("UserRating", typeof(ScaledAnswer), typeof(Rating), new PropertyMetadata(new PropertyChangedCallback(RatingChangedCallback)));

Note the callback registered for the PropertyChanged event of the dependency property.  If databinding changes the value of the dependency property, we still need to update the UI to check the right radio button.

private static void RatingChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)


    Rating r = d as Rating;





private void updateUi(ScaledAnswer rating)


    switch (rating)


        case ScaledAnswer.Excellent:

            excellent.IsChecked = true;


        case ScaledAnswer.Good:

            good.IsChecked = true;


        case ScaledAnswer.Neutral:

            neutral.IsChecked = true;


        case ScaledAnswer.Adequate:

            adequate.IsChecked = true;


        case ScaledAnswer.Poor:

            poor.IsChecked = true;




Finally, the user control handles all the radio button “Checked” events and sets the value of the DependencyProperty to the correct value.

The UserControl provided a fairly smooth way of handling the databinding without having to implement a custom control, and could be reused in other contexts.  There’s probably a way to make it a bit more dynamic to handle more radio buttons, etc. but this worked for my particular case.

Thursday, January 22, 2009 12:54:28 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, January 21, 2009

I needed to build a survey (a course evaluation in this case, but name-your-survey…) and I wanted to be able to add new questions and question categories to the database without having to touch my (Silverlight) survey app.  I wanted the basic layout to look like this…


It took a little experimentation, and I’m sure there are other ways to make this work, but here’s what worked for me:

The questions and categories live in the database, like so


Categories contain questions, questions have text, and what we store when the survey is complete are the answers to the questions.

In the XAML, first there is an ItemsControl to deal with the categories, so that each category will have it’s own DataGrid.  The ItemsControl has a DataTemplate that defines what each category name and data grid of questions will look like (some formatting details removed for clarity)

<ItemsControl x:Name="dgPanel" >



            <StackPanel Orientation="Vertical">

                <TextBlock Text="{Binding CategoryName}"/>

                <data:DataGrid x:Name="dgOverall" ItemsSource="{Binding Questions}">


                    <data:DataGridTextColumn Header="Question"

                   Binding="{Binding Text}" IsReadOnly="True"/>

                    <data:DataGridTemplateColumn Header="Rating">



                                <t:Rating UserRating="{Binding Path=Answer, Mode=TwoWay}" />





                                <t:Rating UserRating="{Binding Path=Answer, Mode=TwoWay}"/>











The questions come from a WCF call, and get bound in the form load

void client_GetQuestionsCompleted(object sender, GetQuestionsCompletedEventArgs e)


    dgPanel.ItemsSource = e.Result;


Each row that comes back has the category header text and a collection of questions, so that for each item in the ItemsControl, the text is bound to the header, and the questions are bound to the datagrid.  The DataGridTemplateColumn stuff above maps the Answer property of each question to a UserControl called Rating that contains the radio buttons.  Depending on which radio button gets checked, the value of the user control represents an enum value with their answer.  Because the data binding is defined as TwoWay, the user’s answers are updating in the in-memory copy of the questions, and when the user eventually hits the “Submit” button, the collection of questions (and answers) is sent back to the web service. 

Now I can add new questions to the database and have those questions show up in the survey, and previously submitted evaluations will only have answers for the questions that were present at the time the survey was submitted.  There’s still some work to do here, like setting up groups of questions so that different sets of questions could be used for different circumstances, etc, but this is a decent start.

Wednesday, January 21, 2009 10:23:06 AM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, January 15, 2009

Shaun (my boss) and I are going to be doing a one-day, technically intensive Silverlight event in both Portland (2/12) and Seattle(2/10) next month.  This will be a full day (plus lunch) of in depth, 300-400 level Silverlight content.  Check out our registration site for full session abstracts and time/place details.

From the event copy…

Look past the glitzy, media rich Silverlight demos, to the reality of writing browser-hosted, business-oriented applications. Learn how to leverage your .NET expertise and see how Silverlight can provide your organization with a powerful platform for building web-delivered solutions.

Thursday, January 15, 2009 2:30:33 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, January 05, 2009

We’ll be teaching several classes on the West side in the next few months, including C#/.NET and Practical .NET Debugging.

The C#/.NET class covers the new features in VS 2008/C# 3.0, including LINQ, automatic properties, the new initializer syntax and the var type, as well as the rest of C# and a solid foundation in .NET 3.5 including XML processing, threading, App Domains, etc. 

The Practical .NET Debugging class covers real-world debugging techniques for .NET including the VS 2008 debugger and using WinDbg on .NET code from a practical perspective.

For scheduling details or to register, see our training site.

Monday, January 05, 2009 4:18:30 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, December 16, 2008

This took me quite a while to figure out, so I thought I’d post it. :) 

I’ve got a Silverlight application that calls a web service, that gets some data from SQL Server via LINQ.  The LINQ statement returns an IEnumerable<QuestionCategory>, and each QuestionCategory has a property which is IEnumerable<Question>:


    public class QuestionCategory


        public string CategoryName { get; set; }

        public int CategoryId { get; set; }

        public int Order { get; set; }

        public IEnumerable<Question> Questions { get; set; }



    public class Question


        public string Text { get; set; }

        public ScaledAnswer? Answer { get; set; }


            using (EvalDataContext context = new EvalDataContext())


                var x = from category in context.EvalQuestionCategories

                        select new QuestionCategory()


                            CategoryId = category.CategoryID,

                            CategoryName = category.CategoryText,

                            Order = (int)category.CategoryOrder,

                            Questions = (from q in category.EvalQuestions select new Question() { Text = q.QuestionText }).ToList()


                return x.ToList();


This all worked just fine until it got across the wire to the Silverlight client, where I was consistently getting “The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.”  Helpful?  Sort of.  The first step was to track down what was actually getting serialized on the server side, and why that should be a problem.  Several debugger sessions later, turns out the “Questions” property of the QuestionCategory was really an ObjectMaterializer (an internal LINQ class) and not really a collection of Question objects, despite (and this is the part that really got me) the fact that I was explicitly calling .ToList() on the LINQ expression.  (FYI: .ToArray() produced the same results)

Given the above, it makes sense that this counts as “not a meaningful reply”, but what’s the solution?  ToList or ToArray should have caused the LINQ statement to be realized, I would think, but no.  In the end, it was pretty straightforward, although I’m not sure I agree that it should be necessary. 

    public class QuestionCategory


        public string CategoryName { get; set; }

        public int CategoryId { get; set; }

        public int Order { get; set; }

        public List<Question> Questions { get; set; }


By changing the Questions property from IEnumerable<Question> to List<Question> it was realized in time, and everything was serialized/deserialized properly. 

It took an embarrassingly long time to figure this out, so hopefully this will be googled by some other poor soul facing the same problem. :-)

Tuesday, December 16, 2008 11:19:03 AM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [3]  | 
# Friday, December 12, 2008

I finished up on a customer project this week, and now it’s full time on Education.  We’ve got a ton of new stuff coming with the new year, including some exciting events (details hopefully next week) and some new classes.  We’ll be teaching WPF, Practical .NET Debugging, and some new Silverlight classes in Q1, plus whatever your organization needs delivered at your facility or ours.  If your organization needs any custom training, or you have questions about course offerings, please drop me a line at education@sftsrc.com.

Friday, December 12, 2008 12:55:14 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
# Saturday, November 08, 2008

After the Scrum class last I got a chance to attend a talk hosted by SolutionsIQ on Adopting Scrum in the Enterprise.  Chris Kinsman gave a very interesting talk on his experience adopting Scrum in his organization, how executive sponsorship made a key difference, and how the adoption has proceeded.  I was particularly taken with the idea of a Sustaining Engineering scrum team.  In Chris’s organization, they run 4 scrum teams, and every sprint one of them  does the sustaining engineering, fixing customer issues and releasing hotfixes, etc.  Every sprint they rotate the duty, so the sustaining work is spread around and nobody has to bear the burden all the time.  It also means that everyone gets a better understanding of how the code works and what customer’s are concerned with.  Passing the buck on sustaining was a big issue at Corillian, and I know that I at least really didn’t like being on the hook carrying the support phone for a week at a time. 

Since Agile often gets adopted from the “grassroots” with the development team advocating for it, it was interesting to hear about a successful top-down adoption.  It poses some interesting challenges, but if done correctly the executive sponsorship could really make a big difference to making Scrum successful. 

The biggest advantage I can see to a top-down adoption is that you can work on changing the whole organization at once with a better chance of success.  Several groups I’ve worked with have adopted Scrum/Agile at the development team level, but the rest of the organization has lagged behind.  That tends to mean that the rest of the process is basically waterfall, with a little Agile in the middle.  You start with a requirements gather phase, do a little design, then some “agile” for the construction phase, followed by a formal QA process.  That sort of adoption is better than nothing, but it poses it’s own set of challenges. 

Saturday, November 08, 2008 11:41:00 AM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 

Last week I got the opportunity to take a Certified ScrumMaster class from SolutionsIQ in Seattle.  It was a very good class, and I came away with a deeper understanding of how Scrum is supposed to work.  I’ve actually been working on (nominally) Scrum projects for a while, but the class gave me a chance to catch up on the formal vocabulary and practice the range of skills involved in running a Scrum project. 

Scrum takes a fair amount of discipline to do successfully, I think, but if you can pull it off it provides (in my experience so far) the best way to run a small development team working on a business application.  One of the things that I think hinders Agile adoption is lack of training.  It’s easy to declare a project agile, when what you really mean is “we don’t have a plan”, or “we don’t write anything down” but that’s not likely to achieve the same level of success. :-)  There’s a fair amount of work involved in running a Scrum project, and from that perspective I don’t think it’s any less work than running a traditional waterfall project, you just end up with (hopefully) better results in terms of building working software that meets your product owner’s requirements. 

To that end, I think it’s very valuable to get the team trained on the formal methodology around Scrum (or you agile methodology of choice).  I don’t think that means everyone on the team needs to be a ScrumMaster, but there are a wide range of courses available for introduction a team to Scrum (or whatever) that would really make a difference to a teams successful adoption of the methodology. 

Saturday, November 08, 2008 11:16:11 AM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [2]  | 
# Tuesday, October 07, 2008

I know things have been a bit on the content-free side here lately, so I’m going to try and remedy that with some (you guessed it) content.

When I hear people talking about Continuous Integration (CI) lately one thing that seems to cause a fair amount of misunderstanding is that people talk about CI like it’s a product, not a process.  On the day they set up their CI server (usually CruiseControl) the “have” CI.  I would argue that exactly the opposite is true.  CI is a process, not a product.  More than that, it’s one of those nasty curves that I blocked out of my mind back when I didn’t do very well in Calculus.  You can be forever approaching CI but you never quite get there.  Huh?  Well, if the goal of CI is to (you guessed it again) Integrate Continuously, we can’t ever quite get there because none of us would ever get any real work done.

So rather than “having” CI, we “do” CI, or better yet, we strive for it. 

If that’s the case, what are we really striving for?  We are striving to reduce the amount of time it takes us to do each (micro) integration, and maximize the amount of time that we as developers can spend adding business value to our software products by writing code.  If we can’t add value because we’re busy integrating, we aren’t fulfilling are primary job function.

So: the closer we come to integrating continuously, the less time we should be spending on non-value-adding programming tasks.

Practically speaking, we can’t spend all of our time worrying about integration.  We all have real work to do.  What we can do is work on making the process smoother for everyone.  That means not breaking the build.  Let me back up a second… In order for everyone to be able to maximize their productive work, and maximize that of everyone else on the team, we need to able to commit changes without fear of breaking the build, or causing other people to have to do integration work needlessly.  What that means in practice is that before committing any changes to our source code repository, we should get all the latest changes, run a full build and test cycle, and make sure we haven’t broken anything.  If we have, we need to fix those problems, and go through the process again, getting source, running build and test, etc. until we get a clean cycle.  If that process if followed by everyone on the team, then it should be very very difficult to break the build.  The only way the build should break if everyone follows that process is if changes are being made to the tip of your source control system faster than the get/build/test cycle.  Sometimes that really happens, and I’ll write some other time about how to deal with that. 

So why do builds break?  Because people don’t follow the processes.  Why not?  Usually for one of two reasons:  1) they don’t understand the process, or 2) the get/build/test cycle takes too long.  #2 is the most likely cause, and happens much too frequently.  In the initial literature on CI, Martin Fowler argued that any build/test cycle that takes longer than 10 minutes is likely to cause people not to follow the process.  In practice, I’ve seen that to be the case as well.  As soon as you get the cycle time down, people will start doing what they are supposed to be doing and the build will break less often. 

If you currently have a build that takes too long, then reducing the build/test cycle time becomes part of your CI process.  We’re always working toward the goal, remember.  Make shaving a few seconds here and there off your build process part of the CI process goals.  Every little bit improves your process, and will start paying dividends.

Tuesday, October 07, 2008 1:27:55 PM (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, October 06, 2008
In the spirit of constantly embracing change, as of last week I am now the Director of Education at SoftSource.  What that means in the near term is that I'm going to be spending a bit of time in the classroom.  What that means in the middle term is that I'll be working on expanding our course offerings to encompass a wider range of topics. 

Right now we offer several classes for open enrollment at OHSU's Professional Development Center in Hillsboro (formerly OGI).  This Fall we'll be teaching C# and the .NET Framework (3.5), WPF, WCF and Debugging.  For details see our open enrollment page.  We also do custom training designed specifically around customer's needs, or we can do our standard courseware at your site and time of your choice. 

Now here comes the important part...  All of our instructors are also Software Engineers and Architects that spend the time they aren't in the classroom on customer projects.  That means that they have real-world experience developing real software on a day to day basis, with the latest technology in the field. 

What I'd love to hear back from y'all is what kind of topics you'd be interested in.  Agile development?  Continuous Integration?  Using MS Team Foudation Server?  How to do real-world estimation and planning?  Of course we hope to continue offering technical subjects like advanced .NET development, WPF, Silverlight, and whatever else tickles your collective fancy. 

If you or your organization needs off-the-shelf of custom-design training, or if you have ideas for training you'd like to see us offer please let me know.

Monday, October 06, 2008 11:19:57 AM (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |