Mobile Zone is brought to you in partnership with:

Known for his broad and deep hands-on expertise with Microsoft technologies along with his creative problem-solving and solution-building mindset, Colin is the Principal Architect for Ace of Clouds, as well being a speaker, trainer, author, user group leader, academic advisor, CTO and company director. He has expertise creating rich UI with WPF/Silverlight, cloud development with Azure, mobile development on Windows Phone and business intelligence with SQL Server, along with in-depth knowledge of core technologies such as .NET, OData, WCF, WF, LINQ and WIF. He has been a hands-on Architect for over 17 years having developed award-winning simulation technology with rich UI, cloud-based learning portals and workflow-driven BI systems. He also created the first streaming video community site with Windows Media. Colin has worked in the finance, telecoms, e-learning, Internet communications, learning and gaming industries, with his latest business solutions currently in use by thousands of users world-wide in corporations like GE, HP, O2, Cisco, IBM, Microsoft & Reuters. Colin has posted 2 posts at DZone. View Full User Profile

A Step-by-Step Guide to Building and Deploying your Windows Phone 7 Applications

10.25.2010
| 19301 views |
  • submit to reddit

Add some dots

Now for something visible.

Go to MainPage.xaml (by clicking on the Tab showing with that name).

What you are seeing is XAML (eXtensible Application Markup Language) which is XML used to declare a tree of objects (mostly visual elements).  Roughly speaking, at runtime, the XML element names are used as Type name to instantiate .NET objects (in a hierarchy) and the XML attributes are used to set the properties on the objects.

Delete the XAML shown here from MainPage.xaml – we don’t need it for our UI – and some text will disappear from the design surface.

<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>

 

Insert the following XAML between the opening and closing tags of the Grid element (near the bottom) which has the attribute x:Name=”ContentPanel”

<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>

<TextBlock Grid.Row="0" Grid.ColumnSpan="3" Text="Tap screen to roll" HorizontalAlignment="Center"/>

<Ellipse Grid.Row="1" Grid.Column="0" Width="80" Height="80" Fill="{StaticResource PhoneAccentBrush}" />
<Ellipse Grid.Row="1" Grid.Column="1" Width="80" Height="80" Fill="{StaticResource PhoneAccentBrush}" />
<Ellipse Grid.Row="1" Grid.Column="2" Width="80" Height="80" Fill="{StaticResource PhoneAccentBrush}" />
<Ellipse Grid.Row="2" Grid.Column="0" Width="80" Height="80" Fill="{StaticResource PhoneAccentBrush}" />
<Ellipse Grid.Row="2" Grid.Column="1" Width="80" Height="80" Fill="{StaticResource PhoneAccentBrush}" />
<Ellipse Grid.Row="2" Grid.Column="2" Width="80" Height="80" Fill="{StaticResource PhoneAccentBrush}" />
<Ellipse Grid.Row="3" Grid.Column="0" Width="80" Height="80" Fill="{StaticResource PhoneAccentBrush}" />
<Ellipse Grid.Row="3" Grid.Column="1" Width="80" Height="80" Fill="{StaticResource PhoneAccentBrush}" />
<Ellipse Grid.Row="3" Grid.Column="2" Width="80" Height="80" Fill="{StaticResource PhoneAccentBrush}" />

 

If you’ve done that correctly, the designer will look like this…

 

We have an object to represent a die and we have a grid of dots.  What we need is a way to turn each dot ‘on’ and ‘off’ according to its position and the value of the die.

Binding & Converters

Go back to DieVM.cs

Add this additional using statement right under the others.

using System.Windows.Data;

 

Then add this code just inside the last } bracket at the end of the file.

public class DieValueToDotOpacityConverter : IValueConverter
{
#region IValueConverter Members

int[,] dotmatix = new int[6,9]
{
{
0,0,0,
0,1,0,
0,0,0
}
,
{
0,0,1,
0,0,0,
1,0,0
},
{
0,0,1,
0,1,0,
1,0,0
},
{
1,0,1,
0,0,0,
1,0,1
},
{
1,0,1,
0,1,0,
1,0,1
},
{
1,0,1,
1,0,1,
1,0,1
}
};

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
try
{
int pos = int.Parse((String)parameter);
int dievalue = (int)value - 1;

return (double)((dotmatix[dievalue, pos] == 1) ? 1 : 0);
}
catch
{
return 1;
}
}

public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}

#endregion
}

 

Build the solution again.

This is a value converter that will be used when we ‘bind’ each dot to the value of the die.  Take a look at the array of integers used and you should see the pattern of dots typically used for each die value.  Given a logical position from 0 to 8 and the value of a die, the convertor provides the desired opacity (1 for solid or 0 for transparent).

To be able to apply this convertor to the dots in XAML, we have to introduce into the XAML document, the .NET Namespace in which the converter class resides.

Insert this XML namespace declaration near the top of the MainPage.xaml document, after the last line that also starts “xmls:”

xmlns:local="clr-namespace:DieApp"

 

 

… and then we have to instantiate an instance of the convertor object and give it a name by which we have refer to it elsewhere in the XAML document.

Insert this XAML </Grid.RowDefinitions> on the Grid with x:Name=”LayoutRoot”

<Grid.Resources>
<local:DieValueToDotOpacityConverter x:Key="NTDOC"/>
</Grid.Resources>

 

Now we can add bind on the opacity of each dot using the converter.

Replace the existing Ellipse elements with these ones.

<Ellipse Grid.Row="1" Grid.Column="0" Width="80" Height="80" Fill="{StaticResource PhoneAccentBrush}" Opacity="{Binding Value, Converter={StaticResource NTDOC}, ConverterParameter=0}"/>
<Ellipse Grid.Row="1" Grid.Column="1" Width="80" Height="80" Fill="{StaticResource PhoneAccentBrush}" Opacity="{Binding Value, Converter={StaticResource NTDOC}, ConverterParameter=1}"/>
<Ellipse Grid.Row="1" Grid.Column="2" Width="80" Height="80" Fill="{StaticResource PhoneAccentBrush}" Opacity="{Binding Value, Converter={StaticResource NTDOC}, ConverterParameter=2}"/>
<Ellipse Grid.Row="2" Grid.Column="0" Width="80" Height="80" Fill="{StaticResource PhoneAccentBrush}" Opacity="{Binding Value, Converter={StaticResource NTDOC}, ConverterParameter=3}"/>
<Ellipse Grid.Row="2" Grid.Column="1" Width="80" Height="80" Fill="{StaticResource PhoneAccentBrush}" Opacity="{Binding Value, Converter={StaticResource NTDOC}, ConverterParameter=4}"/>
<Ellipse Grid.Row="2" Grid.Column="2" Width="80" Height="80" Fill="{StaticResource PhoneAccentBrush}" Opacity="{Binding Value, Converter={StaticResource NTDOC}, ConverterParameter=5}"/>
<Ellipse Grid.Row="3" Grid.Column="0" Width="80" Height="80" Fill="{StaticResource PhoneAccentBrush}" Opacity="{Binding Value, Converter={StaticResource NTDOC}, ConverterParameter=6}"/>
<Ellipse Grid.Row="3" Grid.Column="1" Width="80" Height="80" Fill="{StaticResource PhoneAccentBrush}" Opacity="{Binding Value, Converter={StaticResource NTDOC}, ConverterParameter=7}"/>
<Ellipse Grid.Row="3" Grid.Column="2" Width="80" Height="80" Fill="{StaticResource PhoneAccentBrush}" Opacity="{Binding Value, Converter={StaticResource NTDOC}, ConverterParameter=8}"/>

 

So we are now binding the value of a dot’s Opacity to the Value property of some object.  This means value is copied from the Value property of some object to the Opacity property of the Ellipse via the converter.  This happens when the Ellipse is created, and whenever the object with the Value property fires the PropertyChanged event.

Note how we want to bind the Opacity to the Value of a DieVM object, so we need to instantiate a DieVM object.

XAML can be used to declare non-visual .NET objects and properties too.  We are going to create XAML to represent a DieVM object so we have something to see at design time.

Sample Data

Right-click DieApp in Solution Explorer, select Add, then New Item…

(Click for larger image)

 

Select “XML File” as shown, but carefully enter “SampleDieVM.xaml” as the Name.

(Click for larger image)

 

Click Add and then replace the whole contents of the file with this XAML

<local:DieVM
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DieApp"
Value="2"/>

 

Click Reload the designer and you’ll see a message indicating that the design surface is blank because there are no visual objects.

Go back to MainPage.xaml and update the opening Grid element as shown.

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0" d:DataContext="{d:DesignData SampleDieVM.xaml}">

 

And just like that, your design surface should now show the appropriate die dots for a value of 2 (as defined in the SampleDieVM.xaml file. 

 

Go back to the SampleDieVM.xaml file, change the Value attribute and then switch back to MainPage.xaml to see that we now have bound design-time UI.

Runtime Data

We now need to instantiate a DieVM object as runtime, so let’s simply declare one in XAML.

In MainPage.xaml, update the <Grid.Resources> element contents to look like this:

<Grid.Resources>
<local:DieValueToDotOpacityConverter x:Key="NTDOC"/>
<local:DieVM x:Name="MyDie"/>
</Grid.Resources>

 

Then update the <Grid> open tag to look like this, declaring a DieVM instance to use separately for design-time (starting with d:) and at runtime.

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0" d:DataContext="{d:DesignData SampleDieVM.xaml}" DataContext="{StaticResource MyDie}">

 

Press F5 to try the application in the included phone emulator (shown here with option buttons shown when the cursor is near the top right)…

 

We see a single dot representing a 1.  That’s because the DieVM class initialized it to 1.

You can go to DieVM.cs and update this line to another value from 1 to 6 and try running the application again.

private int _value = 1;

 

Published at DZone with permission of its author, Colin Melia.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)