Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UserControl Location in WPF

I am new in WPF, I created a new UserControl MyUserControl.

Now I am surprised: the UserContol does not have a location.

How can I read (by code) myUserControl1.Location in the parent container?

I explain:

I have some Dots (UserControls) that the user can drag in a panel. Actually, I am not sure what kind of Panel this will be... Perhaps Grid.

Now, these dots should be linked with a Line.

Actually, I have a Dot.Head and Dot.Queue properties (also Dots). So, when a Head or Queue is added, I need to dinamically create a link (Line) between them [A]-----[B]. This for this Line I search the Start and End points to set.

Control XAML:

<UserControl x:Class="LinePlan.Stop"
    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" d:DesignHeight="21" d:DesignWidth="80">
    <Canvas>
        <Path Fill="LightBlue" Width="16" Height="16">
            <Path.Data>
                <EllipseGeometry x:Name="Dot" Center="8,8" 
                    RadiusX="4" RadiusY="4"/>
            </Path.Data>
        </Path>
        <TextBlock x:Name="StopText" Text="Eiffel Tower" Canvas.Left="16"/>
    </Canvas>
</UserControl>

Code:

public partial class Stop : UserControl
{
    private Stop head;
    private Stop tail;
    private LineGeometry headLine;
    private LineGeometry queueLine;

    public Stop()
    {
        InitializeComponent();
    }

    public Stop Head
    {
        get { return head; }
        set
        {
            if (head != value)
            {
                head = value;
                if (head == null) 
                {
                    if (headLine != null)
                        headLine = null;
                }
                else
                {
                    headLine = new LineGeometry();
                    headLine.StartPoint = head.DotPosition;
                    headLine.EndPoint = this.DotPosition;

                    // ?? Add this line to the parent
                }

            }
        }
    }

    public Stop Tail
    {
        get { return tail; }
        set { tail = value; }
    }

    public Point DotPosition
    {
        get
        {
            double x = Canvas.GetLeft(this) + this.Dot.Center.X;
            double y = Canvas.GetTop(this) + this.Dot.Center.Y;
            return new Point(x, y);
        }
        set
        {
            Canvas.SetLeft(this, value.X - this.Dot.Center.X);
            Canvas.SetTop(this, value.Y - this.Dot.Center.Y);
        }
    }
}
like image 499
serhio Avatar asked Sep 06 '25 03:09

serhio


1 Answers

The WPF layout system doesn't use absolute positioning, unless you're placing your controls on a container that supports absolute positioning (typically a Canvas). If you're using a Canvas, you can get or set the position of the control using the Canvas.Left, Canvas.Right, Canvas.Top and Canvas.Bottom attached properties:

double x = Canvas.GetLeft(myControl);
double y = Canvas.GetTop(myControl);

Now, if you want the actual location of the control (relative to its parent), you can use the VisualTreeHelper.GetOffset method:

Vector offset = VisualTreeHelper.GetOffset(myControl);
double x = offset.X;
double y = offset.Y;
like image 136
Thomas Levesque Avatar answered Sep 09 '25 18:09

Thomas Levesque