Creating Multiple Instances of a XAML Object in Silverlight

There are a few cases where you need to create many similar objects from a single XAML object definition.  For example, say you were building a chess game in which each square was represented by a Rectangle primitive.  You have several options here:

Create 64 Rectangles in XAML - Terrible!
This option is terrible for several reasons.  First, you will have an enormous XAML file to maintain.  Imagine what a nightmare it would be if you had to change the look of the squares! Second, you are violating the DRY principle.  I could go on, but I think you get the point.

Create the rectangles programmatically - Ok (Maybe)
This option is not great, but works well in some scenarios.  If you have simple objects that do not require much in the way of configuration this may be the way to go.  However, in more complex scenarios it may take a great deal of code to programmatically describe something that is much more concise in XAML format.

Create one rectangle in XAML and use XamlReader.Load to clone the rectangle. - Cool!
This option is somewhat of a compromise.  You get the benefits of XAML to mark-up the object and you get code to tweak various facets of the object (location for example).

Below, is an example of a keyboard key and the accompanying C# code to create multiple keys and position them.

XAML

   1:  <Canvas xmlns="http://schemas.microsoft.com/client/2007">
   2:      <Path Width="50" Height="50" Stretch="Fill" StrokeThickness="3" 
   3:            StrokeLineJoin="Round" Stroke="#FFB8B8B8" 
   4:            Data="F1 M 180.333,140L 230.333,140C 233.095,140 235.333,142.239 235.333,
   5:            145L 235.333,195C 235.333,197.761 233.095,200 230.333,200L 180.333,200C 177.572,
   6:            200 175.333,197.761 175.333,195L 175.333,145C 175.333,142.239 177.572,
   7:            140 180.333,140 Z ">
   8:        <Path.Fill>
   9:          <RadialGradientBrush 
  10:            RadiusX="0.468546" RadiusY="0.468546" Center="0.5,0.5" GradientOrigin="0.5,0.5">
  11:            <RadialGradientBrush.GradientStops>
  12:              <GradientStop Color="#FFFFFFFF" Offset="0"/>
  13:              <GradientStop Color="#FFDBDBDB" Offset="1"/>
  14:            </RadialGradientBrush.GradientStops>
  15:            <RadialGradientBrush.RelativeTransform>
  16:              <TransformGroup/>
  17:            </RadialGradientBrush.RelativeTransform>
  18:          </RadialGradientBrush>
  19:        </Path.Fill>
  20:      </Path>
  21:  </Canvas>


C# Code

   1:  Canvas keyboard = m_control.FindName("KeyboardContainer") as Canvas;
   2:  System.IO.Stream keyboardStream = 
   3:      this.GetType().Assembly.GetManifestResourceStream("Keyboard.KeyboardButton.xaml");
   4:  string keyboardButtonXaml = new StreamReader(keyboardStream).ReadToEnd();
   5:  int keySize = 50;
   6:  int spacing = 2;
   7:   
   8:  for (int i = 0; i < 5; ++i)
   9:  {
  10:      Canvas key = XamlReader.Load(keyboardButtonXaml) as Canvas;
  11:      int xPos = i * (keySize + spacing);
  12:      int yPos =  0;
  13:      key.SetValue<int>(Canvas.LeftProperty, xPos);
  14:      key.SetValue<int>(Canvas.TopProperty, yPos);
  15:      keyboard.Children.Add(key);
  16:  }

The Result

Here is the end result:

Keys


Feedback

# re: Creating Multiple Instances of a XAML Object in Silverlight

Gravatar more explication, or upload a project in zip file please ;) 4/10/2008 8:26 AM | PooLP

Comments have been closed on this topic.