I'm trying to build a WPF user control called "Screen" which has two attached properties that behave as content slots for displaying a collection of controls and a collection of buttons. I'm basing the design for this on a solution found at WPF: template or UserControl with 2 (or more!) ContentPresenters to present content in 'slots'.
When I run the project, where I expect to see my "Screen" control I am instead seeing the string "(Collection)" printed on the screen. There are no binding errors in the output window. Here's my code:
Code behind:
public partial class Screen : UserControl
{
public Screen()
{
this.InitializeComponent();
this.ScreenGrid.DataContext = this;
this.DataContextChanged += this.ScreenDataContextChanged;
this.Content = new ObservableCollection<FrameworkElement>();
this.Buttons = new ObservableCollection<Button>();
}
private void ScreenDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if (this.GetValue(Screen.ScreenContentProperty) != null)
{
foreach (var control in ((ObservableCollection<FrameworkElement>)this.GetValue(Screen.ScreenContentProperty)))
{
control.DataContext = e.NewValue;
}
}
if (this.GetValue(Screen.ButtonsProperty) != null)
{
foreach (var control in ((ObservableCollection<Button>)this.GetValue(Screen.ButtonsProperty)))
{
control.DataContext = e.NewValue;
}
}
}
public ObservableCollection<FrameworkElement> ScreenContent
{
get { return (ObservableCollection<FrameworkElement>)this.GetValue(Screen.ButtonsProperty); }
set { this.SetValue(Screen.ScreenContentProperty, value); }
}
public ObservableCollection<Button> Buttons
{
get { return (ObservableCollection<Button>)this.GetValue(Screen.ButtonsProperty); }
set { this.SetValue(Screen.ButtonsProperty, value); }
}
public static readonly DependencyProperty ScreenContentProperty = DependencyProperty.Register(
"ScreenContent", typeof(ObservableCollection<FrameworkElement>), typeof(Screen),
new PropertyMetadata(new ObservableCollection<FrameworkElement>()));
public static readonly DependencyProperty ButtonsProperty = DependencyProperty.Register(
"Buttons", typeof(ObservableCollection<Button>), typeof(Screen),
new PropertyMetadata(new ObservableCollection<Button>()));
}
XAML:
<UserControl x:Class="Hca.Ims.Wpf.Views.Screen"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d">
<StackPanel x:Name="ScreenGrid">
<ItemsControl ItemsSource="{Binding ScreenContent}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentPresenter Content="{TemplateBinding Content}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<ScrollViewer>
<StackPanel />
</ScrollViewer>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
<ItemsControl ItemsSource="{Binding Buttons}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentPresenter Content="{TemplateBinding Content}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</StackPanel>
</UserControl>
Usage:
<v:Screen>
<v:Screen.ScreenContent>
<TextBlock>Foo</TextBlock>
<TextBlock>Bar</TextBlock>
</v:Screen.ScreenContent>
<v:Screen.Buttons>
<Button>Submit</Button>
<Button>Approve</Button>
</v:Screen.Buttons>
</v:Screen>
Any ideas what I've done wrong?