我有一个 WPF 应用程序,其中包含一些自定义控件(在同一项目内定义),这些控件具有可交换的子部分。作为一个基本示例,假设我有一些 Xaml,例如:
<Border Background="White" CornerRadius="9">
<ContentPresenter/>
</Border>
它用于我的从 ContentControl
派生的类,我们称之为 MrWhiteControl
如果我将 MrWhiteControl
设为 xaml 和代码隐藏文件对(因此它在 ctor 中有一个 InitializeComponent()
调用),那么无论我在 Content
属性有很多问题,例如DataContext
将无法正确继承,并且在绑定(bind)中使用 ElementName
将不起作用。
但是,如果我使用 lookless control - 因此,MrWhiteControl.cs 文件的样式在 Themes/Generic.xaml 中定义(我不关心此应用程序中的主题支持) - 然后一切正常。
我想知道的是为什么会这样。幕后发生了什么,意味着外观控件工作正常,但带有代码隐藏的 xaml 无法正常工作?
我创建了一个example project you can clone from GitHub 。如果运行它,您将看到 ElementName
绑定(bind)在具有代码隐藏的控件(列表中的第二个)中不起作用,但在无外观的控件(底部列表)。
托管内容演示者的外观控件和用户控件之间有什么区别?
最佳答案
编辑:添加了一个解决方案,使绑定(bind)能够在底部使用此方法。
问得好。
AFAICT 这只是因为 DP 的设置方式以及何时根据 NameScope 解析绑定(bind)。
从 MainWindow.xaml
中,您通过代码隐藏为控件分配 DP MyContent
属性,该属性将整个 TextBox
代码作为DP 值。因此此时绑定(bind)尚未解决。
当应用 Binding 时,在 UserControl 的范围内,找不到 ElementName,我们可以验证是否将另一个 TextBox
添加到该 UserControl
中,例如
<StackPanel>
<TextBox Name="textBox" Text="Sampleeeeeeee" />
<ContentPresenter Content="{Binding MyContent, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type LookslessVsUserControl:MrWhiteWithCodeBehind}}}" />
</StackPanel>
现在我们得到了
当绑定(bind)被解析时,新的 TextBox
是在范围内的,而不是来自 MainWindow.xaml
对于 Style
,应用 Style
的范围保持相同,因此它会找到 MainWindow.xaml 的文本框。因此,我们只有一层嵌套,这也可以从 Snoop 中看到
解决方案:
如果您更喜欢通过该方法设置 DP 与控件,您仍然可以使 Binding 正常工作:
在您的 MainWindow.xaml.cs
中,您需要相应地设置 UserControl
的名称范围,以便它不会使用自己的 WPF Xaml NameScope
在 MainWindow.xaml.cs 的 ctor()
中:
Loaded += (sender, args) => NameScope.SetNameScope(problemControl, NameScope.GetNameScope(this));
在 xaml 中我将其命名为 problemControl
例如:
<LookslessVsUserControl:MrWhiteWithCodeBehind x:Name="problemControl">
<LookslessVsUserControl:MrWhiteWithCodeBehind.MyContent>
<TextBlock Text="{Binding ElementName=textBox, Path=Text}" />
</LookslessVsUserControl:MrWhiteWithCodeBehind.MyContent>
</LookslessVsUserControl:MrWhiteWithCodeBehind>
这样,当 UserControl
加载并尝试解析 Binding
时,它应该可以找到 TextBox
并为您提供所需的输出。
关于wpf - 当我有可交换的子部件时,为什么需要使用外观控件而不是 UserControl,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22712206/