Random programming things I'd want to remember

Saturday, October 19, 2013

Implementing your own keyboard on Windows Phone using MVVM pattern

In my previous article on MVVM pattern in Windows phone, I explained the entire model. Today, I will explain the usage of same pattern on Windows Phone in simpler terms. I will show how to implement a bunch of buttons (which can be repurposed for keyboard) on Windows Phone using MVVM. Let's start with a view:

    <Grid x:Name="LayoutRoot" Background="Transparent">
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        <TextBlock Text="{Binding MyText}" />

        <ItemsControl ItemsSource="{Binding MyButtons}" HorizontalAlignment="Center" Padding="0" Grid.Row="1"
                              Style="{StaticResource HorizontalStackPanel}" />


Quite a standard phone page, the first row contains the property we will be changing through the buttons that we create. The second row contains the ItemsControl that will display the collection of newly-created buttons.

What is non-standard about it is the style definiton for ItemsControl (HorizontalStackPanel). The reason for it is that by default, ItemsControl lays out its children in vertical fashion. But if you add the following code into App.xaml file in <Application.Resources> block, your items will be laid out horizontally:

        <Style x:Key="HorizontalStackPanel" TargetType="ItemsControl">
            <Setter Property="ItemsPanel">
                        <StackPanel Orientation="Horizontal" />

Now let's get to the code-behind page, pretty easy too:

public MainPage()
    this.DataContext = new ButtonsViewModel();

And now let's get to the ButtonsViewModel. First, implementing the MyText property in accordance with MVVM:

        private string _myText;
        public string MyText
            get { return _myText; }
                if (_myText == value)
                _myText = value;

Then, implementing the plumbing for INotifyPropertyChanged interface:
//INotifyPropertyChanged implementation
        public event PropertyChangedEventHandler PropertyChanged;
        public void RaisePropertyChanged(string propertyName)
            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(propertyName));

And here we implement the MyButtons property by creating a list of Buttons and adding Buttons one-by-one:

//Buttons property
        public List<Button> MyButtons
                List<Button> buttons = new List<Button>();
                return buttons;
//Button plumbing
        private Button MakeAButton(string letter)
            Button b = new Button
                CommandParameter = letter,
                Content =  new TextBlock { Text = letter, FontSize = 24, FontFamily = new System.Windows.Media.FontFamily("Segoe UI Mono") },
            b.Click += b_Click; 
            return b;
//The magic
        void b_Click(object sender, System.Windows.RoutedEventArgs e)
            string a = (sender as Button).CommandParameter.ToString();
            SomeText += a;

This example is not a classic MVVM implementation, it uses the Button Click event to alter the value of the MyText property. The classic implementation would be to use ICommand, but I chose not to do it here because this is a quick and easy example. Hopefully it can provide the feel for MVVM for those who are trying to understand the pattern.

A word of caution: if you need to fit a lot of buttons on the same row, you will be better off adjusting Margin property on each button.

No comments: