Update: This was a Silverlight Beta 1 example. Beta 2 now has updates to make this even easier. Here is an example.
I can see XamlReader.Load has it's uses for adding FrameworkElements at runtime, but I really hate the way the code looks. Additionally, I don't like the idea of managing a bunch of String.Format statements for my XAML. Things get even more complex when you want to take advantage of events. Luckily, there is an alternative.
Here is an example of adding elements (ellipse, storyboard, doubleanimation) at runtime, and attaching events so that they are removed when the storyboard ends:
public Page()
{
InitializeComponent();
this.MouseLeftButtonUp += new MouseButtonEventHandler(Page_MouseLeftButtonUp);
updateElementCount();
}
public int spriteCount { get; set; }
void Page_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
Point point = e.GetPosition(this);
Ellipse ellipse = new Ellipse();
SolidColorBrush mySolidColorBrush = new SolidColorBrush();
DoubleAnimation animation = new DoubleAnimation();
Storyboard storyBoard = new Storyboard();
spriteCount += 1;
string spriteName =string.Format("SpriteEllipse{0}", spriteCount);
ellipse.SetValue(Ellipse.NameProperty, spriteName);
mySolidColorBrush.Color = Color.FromArgb(255, 0, 0, 0);
ellipse.Fill = mySolidColorBrush;
ellipse.Width = 30;
ellipse.Height = 30;
ellipse.SetValue(Canvas.TopProperty, (point.Y - ellipse.Width/2));
ellipse.SetValue(Canvas.LeftProperty, (point.X - ellipse.Width/2));
LayoutRoot.Children.Add(ellipse);
animation.Duration = new TimeSpan(0,0,3);
animation.From = 1;
animation.To = 0;
animation.SetValue(Storyboard.TargetNameProperty, spriteName);
animation.SetValue(Storyboard.TargetPropertyProperty, "Opacity");
storyBoard.Completed+=new EventHandler(storyBoard_Completed);
storyBoard.SetValue(Storyboard.TargetNameProperty, spriteName);
storyBoard.Children.Add(animation);
LayoutRoot.Resources.Add(storyBoard);
storyBoard.Begin();
updateElementCount();
}
void storyBoard_Completed(object sender, EventArgs e)
{
Storyboard storyBoard = (Storyboard)sender;
string spriteName = storyBoard.GetValue(Storyboard.TargetNameProperty).ToString();
FrameworkElement sprite = (FrameworkElement)LayoutRoot.FindName(spriteName);
LayoutRoot.Children.Remove(sprite);
LayoutRoot.Resources.Remove(storyBoard);
updateElementCount();
}
void updateElementCount()
{
this.txtChildren.Text = string.Format("Children.Count = {0}", LayoutRoot.Children.Count());
this.txtResources.Text = string.Format("Resources.Count = {0}", LayoutRoot.Resources.Count);
}