Leveraging the add vocabulary word view model from last time, we now turn our attention to creating the associated view. Once we have that, we can wire everything up into a working WPF application.

Add vocabulary word view

After creating a new WPF user control called AddVocbularyWordView, creating a layout that mirrors our previous mockup is pretty easy. (We create a user control because we want to be swapping different views in and out. Using a Window would result in a lot of flickering - and worse.)

Aside: Some developers deride XAML for being verbose. This can be somewhat true for XAML generated by tools (where additional attributes are often included to over control the layout), but we’re not going to do that. We’ll write all our XAML by hand. Done this way, XAML isn’t particularly long winded. It’s more the case that carefully specifying the user experience requires a lot of detail. This results in a lot of configuration. This would be true for any UX framework.

The most interesting bits relate to the data entry fields and their data binding:

<TextBox 
    Text="{Binding Spelling, Delay=250, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
    TextAlignment="Center"
    Grid.Row="4"
    Grid.Column="1"/>

I’m pretty sure that the text alignment and grid properties are (at least moderately) self-explanatory - but what’s going on with the Text property?

If you haven’t seen XAML data binding before this can look a little intimidating; let’s break it down.

  • The {Binding ...} syntax is a bit of parsing magic that tells the XAML reader to configure data-binding on this field. I like the way that this means any property is potentially data-bindable, not just Text.
  • Each data binding has a Path property to specify which view model property should be read. As Path is the default, you can omit it and just name the actual property (in this case, Spelling).
  • We set Mode=TwoWay to ensure that changes flow in both directions: changes in the view model are shown in the textbox, and changes made in the TextBox are propagated back into the view model.
  • By default, data binding triggers only when you change focus between fields. Its more useful for the view model to be updated more often, so we set UpdateSourceTrigger=PropertyChanged. This ensures the model is updated every time the Text property changes, potentially for every keystroke.
  • To slow down the pace of updates (so that we don’t have a large rush of updates if our user types quickly), we specify a delay. This is the number of milliseconds delay from a change until the view model is updated.

The data bindings for the other data entry fields (Pronunciation and Phrase) are set up the same way.

Main Window

Now we need a host window in which to display the current user control. To build this, take the sample MainWindow generated in our project and replace its content with this:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>

    <ContentControl x:Name="Shell"/>

</Grid>

The ContentControl will act as the actual host to our views - everything else provides a framework we can use for other things later on. We give it a name (Shell) so that we can access it from code, swapping out different user controls as our application state changes.

Next time, we get to fire up our application for the first time.

Prior post in this series:
Add Word View Model
Next post in this series:
First Light

Comments

blog comments powered by Disqus