Reputation: 87
Sorry to ask this one, as I've found lots of similar questions, yet somehow the solutions that have worked for them don't seem to apply here...
I have a number of custom controls which generate paths (some are static, some are bound to values that update).
I am displaying these on a single itemscontrol (using a canvas as the itemspaneltemplate), and I need to grab the X & Y position of the individual items. XAML for one of the items shown below:
<Style TargetType="{x:Type pg:GraphVertexBelt}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type pg:GraphVertexBelt}">
<Border Background="Transparent">
<StackPanel>
<Canvas Width="225" Height="20">
<Ellipse Height="10" Width="10" Canvas.Left="10"/>
<Ellipse Height="10" Width="10" Canvas.Left="220"/>
<Line X1="15" Y1="0.5" X2="225" Y2="0.5"/>
</Canvas>
<Label Content="{Binding Item.Tag.Title}" HorizontalAlignment="Center"/>
</StackPanel>
</Border>
</ControlTemplate>
</Setter>
</Setter>
The problem I'm having is that the ActualHeight / ActualWidth are always showing up as zero.
I've Tried:
using a delegate to identify the width after rendering:
Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Render, new Action(() =>
{
Console.Write(Items[0].Item.ActualWidth);
}));
the reason I need to do this is that the width and height of the elements within the control are actually going to be dynamic, and I need to be able to annotate the diagram at appropriate points relative to the position of actual controls.
Any help would be greatly appreciated!
Cheers.
maybe I need to explain the intent a little more clearly for this to make sense. I have a zoomable canvas, within which a collection of controls are displayed. Each control needs to be positioned within the canvas, and I need to know the height and width of these controls on the canvas.
Within each control are a series of paths (as per the example code), these are all positioned relative to one another, so I embedded a canvas within the control. the control also has labels, context menus etc.
If there is another more clean way to approach this then I'm all ears :)
Upvotes: 0
Views: 660
Reputation: 1233
I suggest to create your own Canvas and override Measure and Arrange.
public class MyCanvas : Canvas
{
protected override Size MeasureOverride(Size constraint)
{
Size desiredSize = new Size();
foreach (UIElement child in this.Children)
{
// This is your "control"
child.Measure(constraint);
// This is the size of the "control".
var myControlSize = child.DesiredSize;
}
return desiredSize;
}
protected override Size ArrangeOverride(Size arrangeSize)
{
// When this is called, you should know the DesiredSize of each control
// and you can decide where each control location relative to the canvas.
return arrangeSize;
}
}
Then use MyCanvas as your ItemsPanelTemplate.
Upvotes: 1