我有一个WPF应用程序,其中包含一些具有可交换子部件的自定义控件(在同一项目中定义)。作为一个基本的例子,让我说我有一些像Xaml:
<Border Background="White" CornerRadius="9">
<ContentPresenter/>
</Border>
用于从ContentControl
派生的班级,我们称之为MrWhiteControl
如果我使MrWhiteControl
成为一个xaml和代码隐藏文件对(因此它在ctor中有一个InitializeComponent()
调用),那么我在Content
属性中放置的内容有很多问题,例如DataContext
赢得了正确的继承权,并且在绑定中使用ElementName
无法正常工作。
但是,如果我使用lookless control - 所以MrWhiteControl.cs文件具有在Themes / Generic.xaml中定义的样式(我不关心在这个应用程序中提供支持) - 那么一切正常细
我想知道的是为什么会这样。在幕后发生什么意味着无形控件工作得很好,但带有代码隐藏的xaml无法正常工作?
我创建了example project you can clone from GitHub。如果你运行它,你会发现ElementName
绑定在具有代码隐藏(列表中的第2个)的控件内部不起作用,但是对于无外观控件可以正常工作(列表的底部)。
托管内容演示者的无外观和用户控件之间有什么区别?
答案 0 :(得分:3)
修改:添加了一个解决方案,让绑定在底部使用此方法。
好问题。
AFAICT这只是因为设置DP的方式以及何时解析了关于NameScope的Binding。
从MainWindow.xaml
开始,您为控件分配DP MyContent
属性,并使用代码隐藏,将整个TextBox
代码作为DP值。因此,此时绑定尚未解决。
当应用Binding时,在UserControl的范围内,找不到ElementName,我们可以验证是否在TextBox
中添加了另一个UserControl
,比如说
<StackPanel>
<TextBox Name="textBox" Text="Sampleeeeeeee" />
<ContentPresenter Content="{Binding MyContent, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type LookslessVsUserControl:MrWhiteWithCodeBehind}}}" />
</StackPanel>
现在我们得到
作为解决Binding的点,新的TextBox
是范围内的那个而不是来自MainWindow.xaml的那个
对于Style
,范围在Style
应用的位置保持不变,因此它会找到MainWindow.xaml的文本框。因此,我们只有一级嵌套,我们也可以从Snoop看到
<强>解决方案:强>
如果您喜欢使用控件设置DP,您仍然可以使Binding工作:
在您的MainWindow.xaml.cs
中,您需要相应地为UserControl
设置名称范围,以便它不会使用它自己的WPF Xaml NameScope
ctor()
of MainWindow.xaml.cs
:
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
罚款,并为您提供所需的输出。