06
May
10

Windows Phone 7, MVVM and TDD (Part 5 – creating the basic UI)

by Peter Daukintis

Okay, so we haven’t touched on any of the user interface yet but this supports the theory that we should be able to develop the user interface independently of the code. So, these are the areas we need to create for the user interface:

  • Create the user name and password inputs
  • Create a way to execute the login command
  • Create a busy indicator UserControl
  • Create a transition to a welcome screen after successfully logging in

I am going to use Expression Blend 4 RC for this part of the post as I can work more quickly inside Blend – also you will need Microsoft Expression Blend Add-in Preview 2 for Windows Phone and Microsoft Expression Blend Software Development Kit Preview 2 for Windows Phone all of which can be downloaded here http://www.microsoft.com/expression/windowsphone/.

Opening the solution up in Expression Blend looks like this:

WP7LoginRxpressionBlend

So, let’s start by dragging some input controls and a button:

            <TextBlock Text="{Binding Welcome}"
                       Style="{StaticResource PhoneTextNormalStyle}"
                       HorizontalAlignment="Center"
                       VerticalAlignment="Center"
                       FontSize="30" Margin="0,592,-12,6" />
            <Button Content="{Binding LoginButtonName}" Margin="187,239,7,0" VerticalAlignment="Top" Height="114">
            </Button>
            <TextBox Height="31" HorizontalAlignment="Left" Margin="137,57,0,0" 
                     Text="{Binding UsernameText, Mode=TwoWay, UpdateSourceTrigger=Explicit}" 
                     VerticalAlignment="Top" Width="336">
            </TextBox>
            <PasswordBox Height="31" HorizontalAlignment="Left" Margin="137,144,0,0" 
                     Password="{Binding PasswordText, Mode=TwoWay, UpdateSourceTrigger=Explicit}" 
                     VerticalAlignment="Top" Width="336" PasswordChar="*">
            </PasswordBox>
            <TextBlock HorizontalAlignment="Left" Margin="18,79,0,0"
                       Text="{Binding UsernameLabel}" VerticalAlignment="Top" TextAlignment="Right" />
            <TextBlock HorizontalAlignment="Left" Margin="33,167,0,0"
                       Text="{Binding PasswordLabel}" VerticalAlignment="Top" />

and adding some additional properties to our view model:

        public string ApplicationTitle { get { return "Application"; } }

        public string ListName { get { return "Login:"; } }

        public string LoginButtonName { get { return "Login"; } }

        public string Welcome { get { return "Welcome to My Application"; } }

        public string UsernameLabel { get { return "User Name :"; } }

        public string PasswordLabel { get { return "Password :"; } }

results in the following user interface (the view model is already bound to the DataContext of the page using the MVVM Light ViewModelLocator class):

WP7BasicUI

So, the text input parameters are bound we need to bind the click from the login button to the Login Command exposed by the MainViewModel. We will wire the button up using the EventToCommand behavior included in the MVVM Light framework. Silverlight behaviors allow some functionality to be associated with a FrameworkElement by dragging it from the toolbox onto the element in Expression Blend. To achieve this carry out the following:

WP7LoginBlendBehaviors

  • Drag EventToCommand out onto the Login button.
  • With the EventToCommand object selected in the Objects & Timelines view configure it via the properties pane.

     

    WP7LoginCommandProps

  • Click on the small blob to the right of the Command input box and choose data-binding from the options to display the data-binding dialog:

     

    WP7LoginDataBindingDlg

    from here you can see all of the view model properties and can select the LoginCommand property to complete the data-binding….nice.

    • Set the MustToggleIsEnabled to true as we want to automatically disable the button if the command is unavailable and also set the Event Name to Click if it isn’t already.

    Unfortunately, this is not enough for the behaviour I was looking for since in Silverlight there is no option to set the UpdateSourceTrigger to fire when the property changes, the best we can do is when the control loses focus. As a result the login button does not disable/enable when the fields are empty – until focus is lost from the input controls. To remedy this I have added some custom behaviors:

    namespace WP7Login.Behaviors
    {
        public class DataBindTextBoxOnPropertyChangedBehaviour : Behavior<TextBox>
        {
            public BindingExpression BindingExpression { get; set; }
    
            protected override void OnAttached()
            {
                base.OnAttached();
    
                BindingExpression = AssociatedObject.GetBindingExpression(TextBox.TextProperty);
                AssociatedObject.TextChanged += AssociatedObject_TextChanged;
            }
    
            protected override void OnDetaching()
            {
                base.OnDetaching();
                BindingExpression = null;
            }
    
            private void AssociatedObject_TextChanged(object sender, TextChangedEventArgs e)
            {
                if (BindingExpression != null)
                {
                    BindingExpression.UpdateSource();
                }
            }
        }
    }
    

     

    and a similar one aimed at a password box. Once recompiled these will be available via the Assets panel in Blend and can be dragged onto the user name input and the password input boxes appropriately.

    Also, CanExecute in MainViewModel must be implemented

            private bool CanExecuteLogin()
            {
                return UsernameText.Length > 0 && PasswordText.Length > 0;
            }
    
    

    And also the RaiseExecuteChanged event must be raised in response to the data in the text boxes changing – this can be achieved by the following:

                PropertyChanged += MainViewModel_PropertyChanged;
    
    

    Subscribe to the property changed event on the view model with this handler:

            void MainViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
            {
                if (e.PropertyName == "UsernameText" || 
                    e.PropertyName == "PasswordText")
                {
                    var relayCommand = LoginCommand as RelayCommand;
                    if (relayCommand != null)
                    {
                        relayCommand.RaiseCanExecuteChanged();
                    }
                }
            }
    

    Finally we get the required behaviour – if either username text box or the password box is empty the login button is disabled otherwise it is enabled as we type.

    So, that’s the basic user interface in place – next we move to the loading screen and the transition when logged in….

  • Technorati Tags: ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,

    Windows Live Tags: MVVM,Part,Peter,Daukintis,Okay,haven,user,interface,supports,theory,code,Create,password,indicator,UserControl,transition,Expression,Blend,Microsoft,Preview,Software,Development,solution,TextBlock,Text,Welcome,Style,StaticResource,PhoneTextNormalStyle,HorizontalAlignment,Center,VerticalAlignment,FontSize,Margin,Button,Content,LoginButtonName,TextBox,Left,UsernameText,Mode,TwoWay,UpdateSourceTrigger,Explicit,Width,PasswordBox,PasswordText,PasswordChar,UsernameLabel,TextAlignment,PasswordLabel,ApplicationTitle,Application,ListName,Login,Name,DataContext,ViewModelLocator,Command,MainViewModel,wire,EventToCommand,framework,FrameworkElement,element,reference,archive,Open,Assets,panel,Drag,Objects,Timelines,pane,Click,data,LoginCommand,Event,behaviour,option,result,custom,Behaviors,DataBindTextBoxOnPropertyChangedBehaviour,Behavior,BindingExpression,AssociatedObject,GetBindingExpression,sender,TextChangedEventArgs,UpdateSource,Once,Also,CanExecute,CanExecuteLogin,Length,response,Subscribe,handler,PropertyChangedEventArgs,PropertyName,RelayCommand,areas,parameters,options,boxes


    0 Responses to “Windows Phone 7, MVVM and TDD (Part 5 – creating the basic UI)”



    1. Leave a Comment

    Leave a Reply

    Fill in your details below or click an icon to log in:

    WordPress.com Logo

    You are commenting using your WordPress.com account. Log Out / Change )

    Twitter picture

    You are commenting using your Twitter account. Log Out / Change )

    Facebook photo

    You are commenting using your Facebook account. Log Out / Change )

    Google+ photo

    You are commenting using your Google+ account. Log Out / Change )

    Connecting to %s


    Follow

    Get every new post delivered to your Inbox.

    %d bloggers like this: