I've been working on a control for a while that can be used to repeat a layout in our application. It's working great but the problem is that the controls inside the layout control aren't participating in the logical tree.
It's a custom control with a left header, a right header a body and a standard footer.
Generic.xaml:
<Style TargetType="{x:Type local:FrameControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:FrameControl}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid>
<Border VerticalAlignment="Top" Height="50" Background="LightGray"/>
<DockPanel Background="{TemplateBinding HeaderColor}">
<ItemsControl ItemsSource="{TemplateBinding HeaderLeftContent}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel DockPanel.Dock="Left" FlowDirection="LeftToRight" HorizontalAlignment="Left"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
<ItemsControl ItemsSource="{TemplateBinding HeaderRightContent}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel DockPanel.Dock="Right" Height="40"
Margin="5, 5, 5, 0" VerticalAlignment="Top"
Orientation="Horizontal" FlowDirection="RightToLeft"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</DockPanel>
<Border BorderThickness="1" BorderBrush="Black" Margin="0,49,0,0" Background="White">
<ItemsControl ItemsSource="{TemplateBinding BodyContent}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<DockPanel Background="White" Margin="5"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Border>
<Border VerticalAlignment="Bottom" Height="0" Background="LightGray"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
FrameControl.cs
public class FrameControl : Control
{
public Brush HeaderColor
{
get { return (Brush)GetValue(HeaderColorProperty); }
set { SetValue(HeaderColorProperty, value); }
}
public static readonly DependencyProperty HeaderColorProperty =
DependencyProperty.Register("HeaderColor", typeof(Brush), typeof(FrameControl), new UIPropertyMetadata(null));
public Collection<Object> HeaderLeftContent
{
get { return (Collection<Object>)GetValue(HeaderLeftContentProperty); }
set { SetValue(HeaderLeftContentProperty, value); }
}
public static readonly DependencyProperty HeaderLeftContentProperty =
DependencyProperty.Register("HeaderLeftContent", typeof(Collection<Object>), typeof(FrameControl),
new UIPropertyMetadata(null));
public Collection<Object> HeaderRightContent
{
get { return (Collection<Object>)GetValue(HeaderRightContentProperty); }
set { SetValue(HeaderRightContentProperty, value); }
}
public static readonly DependencyProperty HeaderRightContentProperty =
DependencyProperty.Register("HeaderRightContent", typeof(Collection<Object>), typeof(FrameControl),
new UIPropertyMetadata(null));
public Collection<Object> BodyContent
{
get { return (Collection<Object>)GetValue(BodyContentProperty); }
set { SetValue(BodyContentProperty, value); }
}
public static readonly DependencyProperty BodyContentProperty =
DependencyProperty.Register("BodyContent", typeof(Collection<Object>), typeof(FrameControl),
new UIPropertyMetadata(null));
static FrameControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(FrameControl), new FrameworkPropertyMetadata(typeof(FrameControl)));
}
public FrameControl()
{
SetValue(HeaderLeftContentProperty, new Collection<Object>());
SetValue(HeaderRightContentProperty, new Collection<Object>());
SetValue(BodyContentProperty, new Collection<Object>());
}
}
Usage example
<fc:FrameControl>
<fc:FrameControl.HeaderLeftContent>
<Label Content="Left content of the header"/>
</fc:FrameControl.HeaderLeftContent>
<fc:FrameControl.HeaderRightContent>
<Button>
<TextBlock Text="Example button"/>
</Button>
<ComboBox SelectedIndex="0">
<ComboBoxItem Content="Filter A"/>
<ComboBoxItem Content="Filter B"/>
<ComboBoxItem Content="Filter C"/>
</ComboBox>
</fc:FrameControl.HeaderRightContent>
<fc:FrameControl.BodyContent>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" Content="name"/>
<TextBox Grid.Row="0" Grid.Column="2"/>
<Label Grid.Row="1" Grid.Column="0" Content="Type name"/>
<TextBox Grid.Row="1" Grid.Column="2" />
<Label Grid.Row="2" Grid.Column="0" Content="Keyword"/>
<TextBox Grid.Row="2" Grid.Column="2"/>
<Label Grid.Row="3" Grid.Column="0" Content="Parameter"/>
<ComboBox Grid.Row="4" Grid.Column="0" SelectedIndex="0">
<ComboBoxItem Content="Width"/>
<ComboBoxItem Content="Height"/>
</ComboBox>
<ComboBox Grid.Row="4" Grid.Column="1" SelectedIndex="0">
<ComboBoxItem Content="..."/>
<ComboBoxItem Content="="/>
<ComboBoxItem Content="<"/>
<ComboBoxItem Content=">"/>
</ComboBox>
<TextBox Grid.Row="4" Grid.Column="2"/>
</Grid>
</fc:FrameControl.BodyContent>
</fc:FrameControl>
I've tried using different type of properties to hold the elements for the different region like UIElementCollection but that made no difference. I also tried manually adding the controls to the logical tree, but I did not succeed in that. Am I missing something?