代码之家  ›  专栏  ›  技术社区  ›  serhio

WPF中的用户控件位置

  •  2
  • serhio  · 技术社区  · 14 年前

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

    现在我很惊讶:用户控制没有位置。

    如何读取(按代码)myUserControl1。 Location 在父容器中?

    我解释说:

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

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

    实际上,我有一个 Dot.Head Dot.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);
            }
        }
    }
    
    2 回复  |  直到 14 年前
        1
  •  3
  •   Thomas Levesque    14 年前

    WPF布局系统不使用绝对定位,除非将控件放在支持绝对定位的容器上(通常是 Canvas )如果你用的是 帆布 ,可以使用 Canvas.Left , Canvas.Right , Canvas.Top Canvas.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;
    
        2
  •  1
  •   Martin Liversage    14 年前

    元素(如用户控件)通常放置在WPF中的面板中。根据使用的面板,该面板可能会向用户控件添加一些附加属性。如果用户控件放置在 Canvas 它将获取附加属性 Left , Top , Right Bottom . 但是,如果将用户控件放置在 Grid 它将获取附加属性 Row Column (还有更多)。其他面板如 StackPanel 不会附加任何属性。没有通用的用户控制位置。

    Panels Overview

    Attached Properties Overview

    假设您正在使用 帆布 作为面板,您可以访问 顶部 属性如下:

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