Note that there are some explanatory texts on larger screens.

plurals
  1. POBuilding a Panel-like Custom Control with Attached Properties
    text
    copied!<p>I'm attempting to implement a WPF custom control that displays two collections of <code>FrameworkElement</code> objects in two separate panels. The control derives from <code>ItemsControl</code> and has a <code>Canvas</code> which has <code>IsItemsHost="True"</code> set. Additionally, I have a <code>Collection&lt;FrameworkElement&gt;</code> named <code>OtherItems</code> which I would like to display in a different <code>Canvas</code>. </p> <p>The custom control defines an attached property: <code>myControl.Position</code> which determines the X position of the item within its canvas. The control also defines a <code>MinValue</code> and <code>MaxValue</code> dependency properties. The control calculates uses the <code>MinValue</code>, <code>MaxValue</code> and <code>control.Position</code> properties to place the <code>UIElement</code>'s at the proper position:</p> <p><code>&lt;----------0----------&gt;</code> is the result of: MinValue=10, MaxValue=110, myControl.Position=60</p> <p>I can handle positioning for items that are in the <code>myControl.Items</code> container, but items that are in <code>myControl.OtherItems</code> have a null <code>Parent</code> reference:</p> <pre><code>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); } } } &lt;!--Within the myControl's template--&gt; &lt;Canvas IsItemsHost="True" x:Name="PART_ItemCanvas"/&gt; &lt;ItemsControl ItemsSource="{TemplateBinding OtherItems}"&gt; &lt;ItemsControl.ItemsPanel&gt; &lt;ItemsPanelTemplate&gt; &lt;Canvas x:Name="PART_OtherItemCanvas"/&gt; &lt;/ItemsPanelTemplate&gt; &lt;/ItemsControl.ItemsPanel&gt; &lt;/ItemsControl.ItemContainerStyle&gt; &lt;!-- As used --&gt; &lt;custom:myControl MaxValue="1000" MinValue="-250"&gt; &lt;custom:myControl.Items&gt; &lt;Button myControl.Position="0"/&gt; &lt;SomethingElse myControl.Position="25"/&gt; &lt;Etc myControl.Position="100"/&gt; &lt;/custom:myControl.Items&gt; &lt;custom:myControl.OtherItems&gt; &lt;Button myControl.Position="20"/&gt; &lt;Label myControl.Position="300"/&gt; &lt;/custom:myControl.OtherItems&gt; &lt;/custom:myControl&gt; </code></pre> <p>How can I handle the call to <code>OnPositionChanged</code> 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 <code>Grid.Row</code> and <code>DockPanel.Dock</code>, but how do they manage it?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload