如何在XAML中相对于另一控件中的子元素定位

如何在XAML中相对于另一控件中的子元素定位,xaml,uwp,uwp-xaml,relativepanel,Xaml,Uwp,Uwp Xaml,Relativepanel,在UWP应用程序中,我有一个带有一些子控件(文本框、标签等)的自定义UserControl。我有一个页面,其中包含作为子元素的UserControl。现在,我想在UserControl下面放置一个按钮,并使用RelativePanel将其与该控件的一个子文本框对齐。我想不出访问子元素的方法 例如,我有一个自定义控件: <UserControl x:Class="Sandbox.FooControl" xmlns="http://schemas.microsoft.com/winfx/200

在UWP应用程序中,我有一个带有一些子控件(文本框、标签等)的自定义UserControl。我有一个页面,其中包含作为子元素的UserControl。现在,我想在UserControl下面放置一个按钮,并使用RelativePanel将其与该控件的一个子文本框对齐。我想不出访问子元素的方法

例如,我有一个自定义控件:

<UserControl
x:Class="Sandbox.FooControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Sandbox"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">

<Grid>
    <TextBox
        x:Name="TheTextBoxIWantToAlignWith"
        x:FieldModifier="public"/>
</Grid>

现在我想与“我想与之对齐的文本框”对齐:


显然这不起作用(“RelativePanel错误:当前上下文中不存在名称'Foo.TheTextBoxIWantToAlignWith'。”)。我试过:

  • 在子文本框中将FieldModifier设置为public
  • 在代码隐藏中将文本框作为公共属性公开
  • 在代码隐藏中将文本框作为从属属性公开

  • 我确实希望避免将UserControl扁平化到父页面中,因为它可以在其他地方重用。有没有办法做到这一点

    我最终用代码隐藏解决了这个问题,类似于Lindsay的建议。我连接到LayoutUpdated事件,该事件计算并设置了边距。大概是这样的:

        private void AlignButton()
        {
            var transform = Foo.TheTextBoxIWantToAlignWith.TransformToVisual(RootPanel);
            var textBoxRightEdge = transform .TransformPoint(new Point()).X + Foo.TheTextBoxIWantToAlignWith.ActualWidth;
            var rightMargin = RootPanel.ActualWidth - textBoxRightEdge;
    
            if (Math.Abs(TheButtonIWantToAlign.Margin.Right - rightMargin) >= 1)
                TheButtonIWantToAlign.Margin = new Thickness(0, 0, rightMargin, 0);
        }
    

    您是否可以在用户控件上创建一个
    DependencyProperty
    ,该属性绑定到我希望与控件边缘对齐的文本框的边距/填充,然后将
    按钮的边距/填充绑定到该属性?您能告诉我有此要求的原因吗?将其与绑定一起使用似乎更复杂?@Lindsay提供了一个很好的解决方法,你可以参考。我可能过度简化了这个例子。在实际场景中,文本框左侧有一个宽度未知的标签(取决于文本),因此边距/填充无效。
    
        private void AlignButton()
        {
            var transform = Foo.TheTextBoxIWantToAlignWith.TransformToVisual(RootPanel);
            var textBoxRightEdge = transform .TransformPoint(new Point()).X + Foo.TheTextBoxIWantToAlignWith.ActualWidth;
            var rightMargin = RootPanel.ActualWidth - textBoxRightEdge;
    
            if (Math.Abs(TheButtonIWantToAlign.Margin.Right - rightMargin) >= 1)
                TheButtonIWantToAlign.Margin = new Thickness(0, 0, rightMargin, 0);
        }