Aha! Okay, I may not fully understand all the requirements, but the following demo will show how to dynamically create a user control and then have that user control close itself, remove itself from the containing page and fire an event to the page so that the page can clean up any associated other controls that might be left laying about.
This is based on the User Control sample that goes with the video that hasn't yet been posted (you don't mind that, do you?) but will be in a couple days. I'll strip it down so as not to get hung up in the parts we don't care about.
First, let's look at the effects. When the application begins there is just a single button marked "Create".
Clicking on that button creates two text blocks and two user controls,
In the UserControl video the User Controls are quite nicer looking but here we're interested in their ability to self-destruct; hence the close button.
When you click the close button, not only does the User Control remove itself from its parent panel's children collection, it raises an event to which the page can subscribe so that it can clean up anything else that might be lingering about; in this case the text block (which is not part of the control). Thus, if I close the upper control, I want also to remove the "Event Address" prompt.
Here's how it all works. I assume we have the custom control already and I add the button to it. The key is to give that user control its own EventArgs type (to hold its unique ID ) and thus also give it a delegate and an event.
public partial class AddressUserControl : UserControl
{
public class AddressEventArgs : RoutedEventArgs
{
public object Tag { get; private set; }
public AddressEventArgs(object theTag)
{
this.Tag = theTag;
}
}Notice both that AddressEventArgs is derived from RoutedEventArgs adn that it is nested within AddressUserControl (my User Control). It has a constructor and a public property called Tag (to parallel the idea that the control itself has a Tag of type object).
We now give the control a delegate and an event
public delegate void AddressEventHandler(object o, AddressEventArgs e);
public event AddressEventHandler Closed;The closed event is what the page will subscribe to, in order to be alerted when the control is closed. This event is fired as part of the control's handling of the button's click event,public AddressUserControl()
{
InitializeComponent();
Close.Click += new RoutedEventHandler(Close_Click);
}
void Close_Click(object sender, RoutedEventArgs e)
{
Panel parent = this.Parent as Panel;
if (parent != null)
{
parent.Children.Remove(this);
if (Closed != null && this.Tag != null)
{
Closed(this, new AddressEventArgs(this.Tag));
}
}
}
In the constructor we wire up the Close.Click; our internal handler for when the button is pressed. That handler does two things; it first makes sure we're in a panel, and if so, it removes us from the panel. It then checks to see if anyone has registered with our Closed event and that our Tag is not null; if so then it fires the Closed event to anyone who is interested.
Creating The Control Dynamically
All of the above falls into place when you see the control created dynamically. The XAML has nothing but the stack panel to hold the dynamically created controls,
Page.xaml
<UserControl x:Class="UserControlDemo.Page"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:jl="clr-namespace:UserControlDemo;assembly=UserContro lDemo"
Width="600" Height="800">
<StackPanel x:Name="MasterContainer" Background="White">
<Button x:Name="Create" Content="Create" Width="60" Height="40" HorizontalAlignment="Left"/>
</StackPanel>
</UserControl>Here's how the control is created in Page.xaml.cs:void Create_Click(object sender, RoutedEventArgs e)
{
TextBlock tb = new TextBlock();
tb.Text = "Event Address";
tb.FontFamily = new FontFamily("Verdana");
tb.FontSize = 24;
tb.HorizontalAlignment = HorizontalAlignment.Left;
tb.Margin = new Thickness(15, 0, 0, 0);
tb.Tag = "1";
MasterContainer.Children.Add(tb);
AddressUserControl auc = new AddressUserControl();
auc.Tag = "1";
auc.Closed += new AddressUserC