A Step-by-Step Guide to Building and Deploying your Windows Phone 7 Applications
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…
Select “XML File” as shown, but carefully enter “SampleDieVM.xaml” as the Name.
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;
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)




