WPF中的UserControl位置

4

我在WPF中是新手,我创建了一个名为MyUserControl的新用户控件。

现在我很惊讶:这个用户控件没有位置。

我该如何在父容器中通过代码读取myUserControl1.Location

我解释一下:

我有几个点(用户控件),用户可以在面板中拖动。实际上,我不确定这将是什么类型的面板……也许是网格。

现在,这些点应该与一条线连接起来。

实际上,我有一个Dot.HeadDot.Queue属性(同样是点)。因此,当添加头部或队列时,我需要动态地创建一个连接(线)在它们之间[A]-----[B]。对于这条线,我需要查找起始点和结束点并进行设置。

控件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>

代码:

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);
        }
    }
}

“队列”这个词是一个伪朋友...我认为你要找的词是“尾巴” ;) - Thomas Levesque
2个回答

6

WPF布局系统不使用绝对定位,除非您将控件放置在支持绝对定位的容器上(通常是Canvas)。如果您使用Canvas,则可以使用Canvas.LeftCanvas.RightCanvas.TopCanvas.Bottom附加属性获取或设置控件的位置:

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

现在,如果你想要控件相对于其父级的实际位置,可以使用VisualTreeHelper.GetOffset方法:

Vector offset = VisualTreeHelper.GetOffset(myControl);
double x = offset.X;
double y = offset.Y;

根据您的解释,我认为适合您的唯一候选面板是Canvas... - Thomas Levesque
我添加了真正的代码... 在设计模式下,NAN作为位置返回... - serhio
我也在运行时进行了测试...请参见上面的代码:this.GetValue(Canvas.LeftProperty)Canvas.GetLeft(this)都返回NAN... - serhio
左侧和顶部的附加属性只有在您明确设置它时才具有值。如果您想要实际值,请使用VisualTreeHelper.GetOffset。 - Thomas Levesque

1

在 WPF 中,元素(如用户控件)通常放置在面板中。根据使用的面板不同,面板可能会向用户控件添加一些附加属性。如果将用户控件放置在 Canvas 中,则会获得附加属性 LeftTopRightBottom。然而,如果将用户控件放置在 Grid 中,则会获得附加属性 RowColumn(以及其他一些属性)。像 StackPanel 这样的其他面板不会附加任何属性。没有通用的用户控件位置。

面板概述

附加属性概述

假设您正在使用 Canvas 作为面板,您可以像这样访问附加的 LeftTop 属性:

Double x = Canvas.GetLeft(myUserControl1);
Double y = Canvas.GetTop(myUserControl1);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接