如何在 WPF 中从另一个 UserControl 绑定或引用一个 UserControl?
How to bind or reference a UserControl from another UserControl in WPF?
在我的应用程序中,我有一个 UserControl
,它托管另一个 UserControl
,如下所示:
<UserControl x:Class="FooControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyApp">
<local:BarControl x:Name="NestedControl" />
</UserControl>
现在在宿主 BarControl
中,我想计算它相对于宿主 FooControl
控件的位置。目前我正在从 FooControl
后面的代码调用 child 控件的成员,如下所示:
this.NestedControl.ComputeRelativePos(this);
在这个方法中,我计算的位置是这样的:
public void ComputeRelativePos(Control relativeTo)
{
var pos = this.TranslatePoint(new System.Windows.Point(0, 0), relativeTo);
// ...
}
现在我想从嵌套的 BarControl
的事件处理程序(例如 SizeChanged
)中删除此调用和 re-compute 位置。我想这样做,这样 BarControl
不需要托管在 FooControl
或另一个控件中,显式调用 ComputeRelativePos
:
public BarControl()
{
this.InitializeComponent();
this.SizeChanged += (sender, args) =>
{
this.ComputeRelativePos(this.OuterControl);
};
}
但是,我不太确定如何为 OuterControl
属性 创建绑定。我已经这样定义了 属性:
public Control OuterControl
{
get { return this.GetValue(OuterControlProperty) as Control; }
set { this.SetValue(OuterControlProperty, value); }
}
public static readonly DependencyProperty OuterControlProperty =
DependencyProperty.Register("OuterControl", typeof(Control), typeof(BarControl), new UIPropertyMetadata(null));
并在 FooControl
标记中定义绑定,如下所示:
<local:BarControl x:Name="NestedControl" OuterControl="{Binding RelativeSource={RelativeSource Self}}" />
但是 OuterControl
似乎设置不正确:
this.SizeChanged += (sender, args) => this.ComputeRelativePos(this.OuterControl); // this.OuterControl is `null`
我还尝试绑定到 FooControl
实例名称 1:
<local:BarControl x:Name="NestedControl"
OuterControl="{Binding RelativeSource={RelativeSource Self}, Path=Name}" />
... 这样我就可以从可视化树中查询它(就像建议的 here),但它也没有用。
所以我的一般问题是,如何访问绑定到 child 的 属性 的 parent 控件?我也会接受解决这个问题的另一种方法,因为我对 XAML/WPF.
相当缺乏经验
提前致谢。
1 当然还要相应地定义 DependencyProperty
。
我不想详细说明你在做什么以及为什么这样做,但要让依赖项 属性 正常工作,你必须更改:
<local:BarControl x:Name="NestedControl"
OuterControl="{Binding RelativeSource={RelativeSource Self}, Path=Name}" />
至:
<local:BarControl x:Name="NestedControl" OuterControl="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}" />
说到这里,您的事件处理程序大小更改将在设置依赖项控制之前命中。控件初始化后设置依赖属性。
但是之后当你调整大小时你会看到 relativeTo 被设置为 FooControl。
在我的应用程序中,我有一个 UserControl
,它托管另一个 UserControl
,如下所示:
<UserControl x:Class="FooControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyApp">
<local:BarControl x:Name="NestedControl" />
</UserControl>
现在在宿主 BarControl
中,我想计算它相对于宿主 FooControl
控件的位置。目前我正在从 FooControl
后面的代码调用 child 控件的成员,如下所示:
this.NestedControl.ComputeRelativePos(this);
在这个方法中,我计算的位置是这样的:
public void ComputeRelativePos(Control relativeTo)
{
var pos = this.TranslatePoint(new System.Windows.Point(0, 0), relativeTo);
// ...
}
现在我想从嵌套的 BarControl
的事件处理程序(例如 SizeChanged
)中删除此调用和 re-compute 位置。我想这样做,这样 BarControl
不需要托管在 FooControl
或另一个控件中,显式调用 ComputeRelativePos
:
public BarControl()
{
this.InitializeComponent();
this.SizeChanged += (sender, args) =>
{
this.ComputeRelativePos(this.OuterControl);
};
}
但是,我不太确定如何为 OuterControl
属性 创建绑定。我已经这样定义了 属性:
public Control OuterControl
{
get { return this.GetValue(OuterControlProperty) as Control; }
set { this.SetValue(OuterControlProperty, value); }
}
public static readonly DependencyProperty OuterControlProperty =
DependencyProperty.Register("OuterControl", typeof(Control), typeof(BarControl), new UIPropertyMetadata(null));
并在 FooControl
标记中定义绑定,如下所示:
<local:BarControl x:Name="NestedControl" OuterControl="{Binding RelativeSource={RelativeSource Self}}" />
但是 OuterControl
似乎设置不正确:
this.SizeChanged += (sender, args) => this.ComputeRelativePos(this.OuterControl); // this.OuterControl is `null`
我还尝试绑定到 FooControl
实例名称 1:
<local:BarControl x:Name="NestedControl"
OuterControl="{Binding RelativeSource={RelativeSource Self}, Path=Name}" />
... 这样我就可以从可视化树中查询它(就像建议的 here),但它也没有用。
所以我的一般问题是,如何访问绑定到 child 的 属性 的 parent 控件?我也会接受解决这个问题的另一种方法,因为我对 XAML/WPF.
相当缺乏经验提前致谢。
1 当然还要相应地定义 DependencyProperty
。
我不想详细说明你在做什么以及为什么这样做,但要让依赖项 属性 正常工作,你必须更改:
<local:BarControl x:Name="NestedControl"
OuterControl="{Binding RelativeSource={RelativeSource Self}, Path=Name}" />
至:
<local:BarControl x:Name="NestedControl" OuterControl="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}" />
说到这里,您的事件处理程序大小更改将在设置依赖项控制之前命中。控件初始化后设置依赖属性。
但是之后当你调整大小时你会看到 relativeTo 被设置为 FooControl。