I'm attempting to implement a WPF custom control that displays two collections of FrameworkElement
objects in two separate panels. The control derives from ItemsControl
and has a Canvas
which has IsItemsHost="True"
set. Additionally, I have a Collection<FrameworkElement>
named OtherItems
which I would like to display in a different Canvas
.
The custom control defines an attached property: myControl.Position
which determines the X position of the item within its canvas. The control also defines a MinValue
and MaxValue
dependency properties. The control calculates uses the MinValue
, MaxValue
and control.Position
properties to place the UIElement
's at the proper position:
<----------0---------->
is the result of: MinValue=10, MaxValue=110, myControl.Position=60
I can handle positioning for items that are in the myControl.Items
container, but items that are in myControl.OtherItems
have a null Parent
reference:
public static readonly DependencyProperty PositionProperty =
DependencyProperty.RegisterAttached("Position", typeof (double), typeof (myControl),
new FrameworkPropertyMetadata(0.0, OnPositionChanged));
public static void OnPositionChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
var element = sender as FrameworkElement;
if (element != null)
{
var container = element.Parent as myControl;
if (container != null)
{
container.PositionElement(element);
}
}
}
<!--Within the myControl's template-->
<Canvas IsItemsHost="True" x:Name="PART_ItemCanvas"/>
<ItemsControl ItemsSource="{TemplateBinding OtherItems}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas x:Name="PART_OtherItemCanvas"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl.ItemContainerStyle>
<!-- As used -->
<custom:myControl MaxValue="1000" MinValue="-250">
<custom:myControl.Items>
<Button myControl.Position="0"/>
<SomethingElse myControl.Position="25"/>
<Etc myControl.Position="100"/>
</custom:myControl.Items>
<custom:myControl.OtherItems>
<Button myControl.Position="20"/>
<Label myControl.Position="300"/>
</custom:myControl.OtherItems>
</custom:myControl>
How can I handle the call to OnPositionChanged
when I do not have access to the sender's parents? I'm assuming this is something that WPF layout controls do all the time, with attached properties like Grid.Row
and DockPanel.Dock
, but how do they manage it?