UserControl as a Popup (WPF, C#) – Part 3
To finish off this popup, we need to be able to define it in XAML and wrap it around a block of XAML code. Why? Because defining grids and other complex items can take a LOT of coding in C#.
I thougth Attached properties would be the best way to do this. Attached Properties are very handy and can be used to easily add elements to existing objects.
Creating the PopupControl in XAML would look like this:
<local:PopupControl x:Name="popup2" Title="Our Title">
<local:PopupControl.Child>
<StackPanel>
<Label Content="Just a label"/>
</StackPanel>
</local:PopupControl.Child>
</local:PopupControl>
The Attached property to enable this looks like this:
public static readonly DependencyProperty ChildProperty = DependencyProperty.RegisterAttached(
"Child",
typeof (UIElement),
typeof (PopupControl),
new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnChildChanged)));
public static UIElement GetChild(DependencyObject obj)
{
return (UIElement)obj.GetValue(ChildProperty);
}
public static void SetChild(DependencyObject obj, UIElement value)
{
obj.SetValue(ChildProperty, value);
}
private static void OnChildChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
PopupControl p = obj as PopupControl;
if (p != null && e.NewValue != null)
{
p.contentContainer.Children.Clear();
p.contentContainer.Children.Add(e.NewValue as UIElement);
}
}
This works very well.
However, I discovered this was not necessary. I could do the same thing with a property. Silly me.
The property:
public UIElement MyChild
{
set
{
contentContainer.Children.Clear();
contentContainer.Children.Add(value);
}
}
The PopupControl in created in XMAL like this:
<local:PopupControl x:Name="popup3">
<local:PopupControl.Title>I like this title</local:PopupControl.Title>
<local:PopupControl.MyChild>
<StackPanel>
<Label Content="Hello Mr. Bean."/>
</StackPanel>
</local:PopupControl.MyChild>
</local:PopupControl>
For a good article on attached properties and how they can be used, look at this article: http://en.csharp-online.net/WPF_Concepts%E2%80%94Attached_Properties
Now I have a popup that does everything we want it to do, but is not a popup at all. Nice!