DCSIMG
July 2011 - Posts - Pavel's Blog
Sign in | Join | Help

Pavel's Blog

Pavel is a software guy that is interested in almost everything
software related... way too much for too little time

July 2011 - Posts

The Cost of Training

Published at Jul 29 2011, 03:38 PM by pavely

A large part of my job is training. I’ve been doing that professionally on and off for the past 13 years. I remember the “good old days” of teaching C and C++, then COM (Component Object Model). These two, C++ and COM (with ATL, no doubt) where the backbone of any productive development on the Microsoft platform, and it all seemed to be possible to do, each with its own training course: 5 days of C++, 5 days of COM (non consecutive, as it’s pretty unrealistic to take some software guy and teach C++ then COM in straight 10 days), but it was possible to start from a C++ guy and get to a COM guy in 5 days.

Then came .NET. Teaching .NET 1.x, a new platform, with a new prominent language, C#, was also feasible. Such training lasted for 5 days as well. Attendees where typically C++ or Java developers, so it just meant learning the new platform, the new C# language - that seemed not too difficult, as C# has many common traits with C++ and Java. Some new concepts, such as garbage collection and finalization, delegates and reflection needed more explanation, as they did not exist in C++, or had different capabilities.

Then .NET 2.0 came along. And again, there was generics, that was inspired by C++ templates, but was very different in capabilities and implementation. C# 2.0 added some new features (not just for generics), such as anonymous delegates and iterators (a.k.a. yield). yield was typically not discussed, and that’s why even today when I teach advanced .NET/C# courses, I always talk about yield – people seemed to miss that powerful feature that is present since 2005. Again, 5 days was the training. This was more difficult – .NET 1.x features were not going away – so .NET 1.x and .NET 2.0 had to be covered.

Then came .NET 3.0. This added WCF, WPF, WF and CardSpace to the .NET arsenal. But the CLR was the same, C# was the same, so these topics were pushed to their own training courses: one for WCF, one for WPF, one for WF, and… CardSpace was usually discarded as being too odd, or at least not that useful.

And then came .NET 3.5. This had major additions, with LINQ and C# 3.0 coming to the fore. C# 3.0 had many new capabilities, most of them leading to LINQ. New training courses tried to cover that as well, all in 5 days. I found that to be very difficult. Starting with a C++ or Java developer, going through the basics of the .NET platform, C# and the CLR is hard enough. Adding LINQ was most of the time overwhelming, and understandably so. Most developers have very little (if any) experience with functional languages, so the concepts related LINQ seem alien, as they are not the usual “procedural” stuff.

Things like multithreading got much more important than before, because of the multicore machines that became the norm. But where would you add that stuff? It’s not just threading itself, it’s synchronization, patterns, the use of kernel objects and more. This may be pushed to an “advanced” course, but usually a basic coverage was pushed to the basic training.

I realized at that time that it was not realistic to get a C++/Java developer up to speed with basic .NET 3.5 and C# 3.0 in 5 straight days. But training centers mostly insisted on it, because clients don’t usually agree to more than 5 days of “lost work” and training costs.

Things weren’t getting better. With .NET 4, things got (naturally) worse. There’s C# 4.0, and more core libraries, such as MEF (Managed Extensibility Framework), that seem as “good to know”. And how about the new Task Parallel Library (TPL)? How does one cram all this in 5 days? Not possible, in my humble opinion.

As a consequence, I designed a 7 day course to cover .NET from the ground up, including all versions of C# and most core libraries, such as reflection and MEF. This, however, did not work well. Few companies agreed to let their employees be away for 7 days. Most see this as too expensive. But the real cost comes later, when developers are unprepared for the tasks ahead, or at least don’t use the best .NET has to offer, topics that could have been accomplished in the extra 2 days. Microsoft’s own MOCs support the 5 days idea – unrealistic, or at least, very superficial treatment of subjects.

The net result of this state of affairs, is that people want to know everything (or at least required to), but unwilling to take the required time to get there. The knowledge ramp is increasing. If we think about the other libraries that surround .NET, some of which essential to do actual work, such as WCF, WPF/Silverlight, ASP.NET (Web Forms, MVC), Entity Framework, WCF Data Services, WCF RIA Services…, the list goes on and on – it’s pretty difficult to become and all around developer. A novice stepping into Microsoft’s world has a lot to learn, and it’s not getting easier.

I believe training should be taken more seriously by the IT industry. It’s not an afterthought – it’s a necessity. And it saves money in the mid and long run. A shift in thinking is required.

Getting Started with Windows Phone Development

Published at Jul 22 2011, 04:56 PM by pavely

I must admit I was reluctant to get into Windows Phone development too deeply because I had no actual device running the Windows Phone OS. An emulator, no matter how good, cannot replace the actual device experience, and for some applications such as games, is simply inadequate.

Well, the excuses are over. I got a Windows Phone device (the Samsung Omnia 7) a few days ago. It’s time to take WP7 development more seriously (but not too seriously, as it’s fun…).

Instead of going with the traditional “hello world”, I’ll go for something a little more ambitious: a kind of guessing game, with the following rules:

  • the program selects a 4 digit number, where all digits being different from one another.
  • the player tries to guess the 4 digit number
  • for each guess, the program responds with a set of full or empty circles. A full circle indicates a correct digit in the correct place (but it doesn’t indicate which one). An empty circle indicates a correct digit that’s out of place.
  • this goes on until the player figures it out or the time runs out.

Let’s get started.

Getting the Tools

The first thing to do is download the Windows Phone 7 SDK, in the Beta 2 version of “Mango” at the time of this writing. This installs project templates for Visual Studio, the WP7 emulator and some other useful libraries. You’re naturally going to need some version of Visual Studio 2010 (the express version works as well).

Creating a New Project

After installation, run VS 2010 and create a new project for a Silverlight windows Phone application:

image

There are various templates to get started, but they’re pretty similar, each one adding something beyond the first template. For this project, I’ll use the basic “Windows Phone Application” template, call it GuessNumber and click OK.

Windows Phone supports two pretty distinct way of programming (although they may also be combined): one is using Silverlight and the other using XNA. Both of these technologies are not new, meaning possibly a less steep curve of learning. If you know Silverlight or WPF, then you’re on a good start with WP7 application development. For more graphical games – XNA is the better choice. And again, If you know XNA for Windows or the XBOX 360, you’re mostly ready to tackle WP7. For a good Smile tutorial on basic XNA development, you can check out the tutorial series I did a few months back (here are the first and last posts in the series).

Coding the game

We get a standard WP7 page deriving from the PhoneApplicationPage (similar somewhat to the standard Silverlight Page class). Inside there is some standard XAML that we need to customize. This is the basic screen I want to get:

image

The main area holds an ItemsControl wrapped in a ScrollViewer that’s going to show the guesses and their results as they come in during play. The “New Game” button starts a new game (obviously), “Restart” resets the clock but keeps the same secret number (a kind of cheat). “Quit Now” forfeits the game and shows the secret combination. Here’s an example of a game running inside the emulator:

SNAGHTML1503ca8

A class named GuessNumberGame takes care of the game logic: generating a secret number and evaluating guesses. Here’s the way a new number is generated:

private void GenerateSecret() {
    var ints = Enumerable.Range(0, 10).ToArray();
    var rnd = new Random();
    for(int i = 0; i < 20; i++)
        Helpers.Swap(ref ints[rnd.Next(10)], ref ints[rnd.Next(10)]);
    _secret = string.Join(string.Empty, ints.Take(NumLength).Select(n => n.ToString()).ToArray());
}

The general strategy is creating a range of numbers 0-9, then shuffling them and finally using the first NumLength digits (currently 4, but can be changed to create an easier or more difficult game).

To evaluate a guess, the EvalGuess method is used:

public bool EvalGuess(string guess, out int inpos, out int justin) {
    inpos = justin = 0;
    if(guess == _secret) {
        inpos = NumLength;
        return true;
    }
    Debug.Assert(guess.Length == _secret.Length);
    justin = guess.Intersect(_secret).Count();
    for(int i = 0; i < _secret.Length; i++)
        if(_secret[i] == guess[i]) {
            justin--;
            inpos++;
        }
    return false;
}

The method returns true on a correct guess. inpos returns the number of digits in correct positions and justin returns the number of digits in incorrect positions.

The MainPage class holds a game instance and handles the UI. I have not created any special MVVM style views or view models in this application as it’s too simple to bother. Some data binding does take place, however. The ItemsControl control is built like so:

<ItemsControl Grid.Row="1" ItemsSource="{Binding Guesses}" >
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <local:GuessItemControl Margin="4" FontSize="25"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate
>
</
ItemsControl
>

There is a data template based around a simple GuessItem class serving as the DataContext of a user control that shows a single row consisting of a guess and its evaluation. The ItemsSource property is bound to a Guesses property, but since no source is indicated, it uses the closest DataContext. In our case, it’s simply set to the MainPage itself (in the constructor). Guesses is an ObservableCollection of GuessItem instances.

Here’s how a GuessItem looks like:

public class GuessItem {
    public string Guess { get; set; }
    public int PosIncorrect { get; set; }
    public int PosCorrect { get; set; }
}

The GuessItemControl class is a user control that builds a line using a combination of code and markup:

<Grid x:Name="LayoutRoot">
     <Grid.ColumnDefinitions>
         <ColumnDefinition />
         <ColumnDefinition />
     </Grid.ColumnDefinitions>
     <TextBlock Text="{Binding Guess}" HorizontalAlignment="Center"/>
     <ItemsControl Grid.Column="1" x:Name="_images">
         <ItemsControl.ItemsPanel>
             <ItemsPanelTemplate>
                 <StackPanel Orientation="Horizontal" />
             </ItemsPanelTemplate>
         </ItemsControl.ItemsPanel>
     </ItemsControl>
 </Grid
>
public GuessItemControl() {
    InitializeComponent();

    Loaded += delegate {
        GuessItem data = DataContext as GuessItem;
        Debug.Assert(data != null);

        for(int i = 0; i < data.PosCorrect; i++)
            _images.Items.Add(new Ellipse { Width = 20, Height = 20, Fill = _fillBrush,
                Stroke = _strokeBrush, StrokeThickness = 2, Margin = new Thickness(2) });
        for(int i = 0; i < data.PosIncorrect; i++)
            _images.Items.Add(new Ellipse { Width = 20, Height = 20,
                Stroke = _strokeBrush, StrokeThickness = 2, Margin = new Thickness(2) });
    };
}

The circles are built dynamically using code. This may not be the most “elegant” way of doing it, but it works and suffices for our purposes here.

Evaluating a guess is handled by the Click event handler of the “Guess” button:

private void OnInputGuess(object sender, RoutedEventArgs e) {
    if(_guess.Text.Length != _game.NumLength) {
        _guess.Focus();
        return;
    }

    int posCorrect, posIncorrect;
    bool win = _game.EvalGuess(_guess.Text, out posCorrect, out posIncorrect);
    _guesses.Add(new GuessItem { Guess = _guess.Text, PosCorrect = posCorrect, PosIncorrect = posIncorrect });
    _guess.Text = string.Empty;
    if(win)
        GameOver(true);
}

The game’s EvalGuess method is consulted, and then a GuessItem object is constructed based on the results and added to the ObservableCollection that is bound to the ItemsControl, so that the results appear immediately.

Running & Debugging the Application

The installed tools allow selecting the target device that we want to deploy to. This is the emulator by default, but we can switch to the actual device (now that I have it…).

image

Debugging is pretty straightforward. You can set breakpoints, inspect variables, etc. whether you’re running on the emulator or the actual device. If running on the device, your app is added to the all applications list and you can run it independently like any other.

If you want to put your creation to the marketplace, you’ll need to tackle a few more details, but that’s for another post.

Other Points of Interest

The TextBox used is just a textbox, but on a phone device the SIP keyboard appears. It’s possible to indicate to WP7 which keyboard style you prefer. In this case, we just need digits, so using the “default” keyboard is inconvenient, causing the player to type way too much and be annoyed. Here’s how we can choose a different set:

<TextBox Width="150" x:Name="_guess" MaxLength="4" TabIndex="0" Background="Green">
    <TextBox.InputScope>
        <InputScope>
            <InputScopeName NameValue="TelephoneNumber" />
        </InputScope>
    </TextBox.InputScope
>
</
TextBox
>

The countdown is handled by a DispatcherTimer object, firing at 1 second intervals. It’s activated when a new game starts:

private void StartNewGame() {
    _game = new GuessNumberGame(4);
    _gameTime = MaximumGameTime;
    _guesses.Clear();
    _timer.Start();
    IsGameRunning = true;
}

It’s configured in the constructor of MainPage. First, some fields:

DispatcherTimer _timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) };
int _gameTime;

Next, handling the Tick event:

_timer.Tick += (s, e) => {
    if(--_gameTime == 0) {
        GameOver(false);
    }
    else
        Caption = string.Format("{0}:{1:D2} Remain", _gameTime / 60, _gameTime % 60);
};

Here’s a link to the entire Solution.

WPF/Silverlight Custom Control Binding Gotcha

Published at Jul 08 2011, 09:45 AM by pavely

When creating custom controls (not user controls) in WPF or Silverlight, the control creator typically supplies a default control template to give a default look to her control, but a client can change that control template using the Template property (inherited from Control). This is the standard way of working.

If some part of the template requires data binding, it’s not supplied with the default template: if it did, a client wanting to replace the template would have to correctly preserve the data binding expressions, which may be difficult or even impossible (if converters are involved, for instance). Instead, the control author creates the bindings in code, alleviating this burden off the client.

Here’s a simple custom control template example:

<Style TargetType="{x:Type local:DemoControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:DemoControl}">
                <Border Background="{TemplateBinding Background}"
                       BorderBrush="{TemplateBinding BorderBrush}"
                       BorderThickness="{TemplateBinding BorderThickness}">
                    <Grid>
                        <Slider x:Name="PART_Slider" Minimum="0" Maximum="100" />
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter
>
</
Style
>

The control itself exposes a dependency property that should be data bound to the supplied slider (if any). The way to “find” that slider is to name it explicitly and advertise on the control class that this named part is significant, and should be supplied:

[TemplatePart(Name = DemoControl.SliderPartName, Type = typeof(RangeBase))]
public class DemoControl : Control {
    public const string SliderPartName = "PART_Slider";

The TemplatePart attribute indicates which name is needed and what minimum type of element is acceptable.

Now, when the control’s template is applied (whether the default template or a custom one), the control looks up the element in its OnApplyTemplate override and hooks data binding, events, or whatever else may be necessary for the control’s intended behavior.

Suppose that in our control, the following dependency property is defined and we would like it to data bind to the found “slider” (something that derives from RangeBase), and that that binding should be a two way binding. Here’s the property’s definition (WPF):

public double TheValue {
    get { return (double)GetValue(TheValueProperty); }
    set { SetValue(TheValueProperty, value); }
}

public static readonly DependencyProperty TheValueProperty =
    DependencyProperty.Register("TheValue", typeof(double), typeof(DemoControl), new UIPropertyMetadata(0.0));

Here’s the start of the OnApplyTemplate override:

public override void OnApplyTemplate() {
    base.OnApplyTemplate();

    var slider = GetTemplateChild(SliderPartName) as RangeBase;
    if(slider != null) {

Now we need to connect the dependency property to the Value property of the RangeBase object.

Here’s one way to make the connection, assuming the requested control exists:

var binding = new Binding("Value");
binding.Mode = BindingMode.TwoWay;
binding.Source = slider;
BindingOperations.SetBinding(this, TheValueProperty, binding);

Since it’s a two way binding (and no converter is needed), there is another way:

var binding = new Binding("TheValue");
binding.Mode = BindingMode.TwoWay;
binding.Source = this;
BindingOperations.SetBinding(slider, Slider.ValueProperty, binding);

This apparently achieves the same thing: both are dependency properties, no converter is needed, so why should we care who is the source and who is the target?

Let’s place the control in some WPF window:

<Window x:Class="CustomControlDemo.MainWindow"
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       xmlns:local="clr-namespace:CustomControlDemo"
       Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <local:DemoControl x:Name="_demo" Margin="10" TheValue="{Binding Text, ElementName=_text1, Mode=TwoWay}"/>
        <TextBox x:Name="_text1" Grid.Row="1"/>
    </Grid
>
</
Window
>

We’ve bound the TheValue property to a text box, so that moving the slider (from the default template) changes the text and vice versa. Surprisingly enough, this works with one of the previous data binding options, but not both. Can you guess which is the “good one”?

The answer is that the first option fails, while the second succeeds. Why? The binding seems the same – it’s two way, no converter, what’s going on?

Curiously enough, if we change the binding in the client, so that the textbox Text property is bound to the TheValue property – everything works in both binding ways!

The solution to this conundrum is that in WPF/Silverlight, a target dependency property may be bound by a single data binding expression. That means that in the following line:

BindingOperations.SetBinding(this, TheValueProperty, binding);

The target is the TheValue property, meaning that it’s bound to something else (as target), and such it loses its original binding.

The moral of the story is: when you’re writing custom controls, bind your dependency properties as source and not as target whenever possible, to give your clients more freedom on how to data bind properties in your control.