WPF ContentControl 内容作为 ContentControl
WPF ContentControl Content as ContentControl
难道不能有多层包含ContentControl的UserControl吗?
我正在尝试为派生的不同模型创建视图,因此我想消除为每个对象类型重新创建视图的需要,而是提供一个 ContentControl 或一个 ContentPresenter 来注入"rest of the view"。但是,我只能用这种方法深入一层。
这是一个简化的示例。(我删除了一些 xmlns)。就我而言,我正在处理更复杂的视图,并试图消除多个地方的重复代码,关注以后的更改。
我有一个 Base UserControl,我们称它为 UserControlLevel1
<UserControl x:Class="ContentControlNesting.UserControlLevel1"
x:Name="userControlLevel1"
xmlns:local="clr-namespace:ContentControlNesting">
<StackPanel>
<TextBlock Text="UserControlLevel1ContentTop"/>
<ContentControl Content="{Binding ElementName=userControlLevel1, Path=ChildContent}"/>
<TextBlock Text="UserControlLevel2ContentBottom"/>
</StackPanel>
</UserControl>
它在 UserControl 上具有以下 DependencyProperty
namespace ContentControlNesting
{
public partial class UserControlLevel1 : UserControl
{
public UserControlLevel1()
{
InitializeComponent();
}
public static readonly DependencyProperty ChildContentProperty = DependencyProperty.Register("ChildContent", typeof(UIElement), typeof(UserControlLevel1), new PropertyMetadata(null));
public UIElement ChildContent
{
get { return (UIElement)GetValue(ChildContentProperty); }
set { SetValue(ChildContentProperty, value); }
}
}
}
ContentControl 将在以下名为 UserControlLevel2 的 UserControl 中使用。这个 UserControl 工作正常,正如我所期望的那样。或者更确切地说,UserControlLevel1 在 UserControlLevel2 中正常工作。
<UserControl x:Class="ContentControlNesting.UserControlLevel2"
x:Name="userControlLevel2"
xmlns:local="clr-namespace:ContentControlNesting">
<local:UserControlLevel1>
<local:UserControlLevel1.ChildContent>
<StackPanel>
<TextBlock Text="UserControlLevel2ContentTop"/>
<ContentControl Content="{Binding ElementName=userControlLevel2, Path=ChildContent}"/>
<TextBlock Text="UserControlLevel2ContentBottom"/>
</StackPanel>
</local:UserControlLevel1.ChildContent>
</local:UserControlLevel1>
</UserControl>
同样,与第一个一样,此 UserControl 上的 ContentControl 有一个 DependencyProperty。我也尝试过使用不同名称的 DependencyProperties。
namespace ContentControlNesting
{
public partial class UserControlLevel1 : UserControl
{
public UserControlLevel1()
{
InitializeComponent();
}
public static readonly DependencyProperty ChildContentProperty = DependencyProperty.Register("ChildContent", typeof(UIElement), typeof(UserControlLevel1), new PropertyMetadata(null));
public UIElement ChildContent
{
get { return (UIElement)GetValue(ChildContentProperty); }
set { SetValue(ChildContentProperty, value); }
}
}
}
好的,那么在这一点上,一切似乎都运行良好。我在 UserControlLevel1 的 ContentControl 中添加了其他内容,并且在我的 UserControlLevel2 UserControl 中添加了另一个 ContentControl。
问题是当我尝试引入 UserControl 或我的 MainWindow 的第 3 层时。我添加到 UserControlLevel2 的 ContentControl 的任何内容都没有出现。
<Window x:Class="ContentControlNesting.MainWindow"
xmlns:local="clr-namespace:ContentControlNesting"
Title="MainWindow" Height="200" Width="300">
<local:UserControlLevel2>
<local:UserControlLevel2.ChildContent>
<StackPanel>
<TextBlock Text="Main Window Content Text"/>
</StackPanel>
</local:UserControlLevel2.ChildContent>
</local:UserControlLevel2>
</Window>
我是不是在尝试做一些不可能的事情?还是我对 ContentControl 和 DependencyProperties 做错了什么?我应该用不同的方法来看待这个问题吗?
有可能。系统无法解析 Binding
中的 ElementName
。解决方案是使用相对绑定。只需替换 UserControlLevel2 中的以下行即可完成:
<ContentControl Content="{Binding Path=ChildContent, RelativeSource={RelativeSource AncestorType={x:Type local:UserControlLevel2}}}"/>
难道不能有多层包含ContentControl的UserControl吗?
我正在尝试为派生的不同模型创建视图,因此我想消除为每个对象类型重新创建视图的需要,而是提供一个 ContentControl 或一个 ContentPresenter 来注入"rest of the view"。但是,我只能用这种方法深入一层。
这是一个简化的示例。(我删除了一些 xmlns)。就我而言,我正在处理更复杂的视图,并试图消除多个地方的重复代码,关注以后的更改。
我有一个 Base UserControl,我们称它为 UserControlLevel1
<UserControl x:Class="ContentControlNesting.UserControlLevel1"
x:Name="userControlLevel1"
xmlns:local="clr-namespace:ContentControlNesting">
<StackPanel>
<TextBlock Text="UserControlLevel1ContentTop"/>
<ContentControl Content="{Binding ElementName=userControlLevel1, Path=ChildContent}"/>
<TextBlock Text="UserControlLevel2ContentBottom"/>
</StackPanel>
</UserControl>
它在 UserControl 上具有以下 DependencyProperty
namespace ContentControlNesting
{
public partial class UserControlLevel1 : UserControl
{
public UserControlLevel1()
{
InitializeComponent();
}
public static readonly DependencyProperty ChildContentProperty = DependencyProperty.Register("ChildContent", typeof(UIElement), typeof(UserControlLevel1), new PropertyMetadata(null));
public UIElement ChildContent
{
get { return (UIElement)GetValue(ChildContentProperty); }
set { SetValue(ChildContentProperty, value); }
}
}
}
ContentControl 将在以下名为 UserControlLevel2 的 UserControl 中使用。这个 UserControl 工作正常,正如我所期望的那样。或者更确切地说,UserControlLevel1 在 UserControlLevel2 中正常工作。
<UserControl x:Class="ContentControlNesting.UserControlLevel2"
x:Name="userControlLevel2"
xmlns:local="clr-namespace:ContentControlNesting">
<local:UserControlLevel1>
<local:UserControlLevel1.ChildContent>
<StackPanel>
<TextBlock Text="UserControlLevel2ContentTop"/>
<ContentControl Content="{Binding ElementName=userControlLevel2, Path=ChildContent}"/>
<TextBlock Text="UserControlLevel2ContentBottom"/>
</StackPanel>
</local:UserControlLevel1.ChildContent>
</local:UserControlLevel1>
</UserControl>
同样,与第一个一样,此 UserControl 上的 ContentControl 有一个 DependencyProperty。我也尝试过使用不同名称的 DependencyProperties。
namespace ContentControlNesting
{
public partial class UserControlLevel1 : UserControl
{
public UserControlLevel1()
{
InitializeComponent();
}
public static readonly DependencyProperty ChildContentProperty = DependencyProperty.Register("ChildContent", typeof(UIElement), typeof(UserControlLevel1), new PropertyMetadata(null));
public UIElement ChildContent
{
get { return (UIElement)GetValue(ChildContentProperty); }
set { SetValue(ChildContentProperty, value); }
}
}
}
好的,那么在这一点上,一切似乎都运行良好。我在 UserControlLevel1 的 ContentControl 中添加了其他内容,并且在我的 UserControlLevel2 UserControl 中添加了另一个 ContentControl。
问题是当我尝试引入 UserControl 或我的 MainWindow 的第 3 层时。我添加到 UserControlLevel2 的 ContentControl 的任何内容都没有出现。
<Window x:Class="ContentControlNesting.MainWindow"
xmlns:local="clr-namespace:ContentControlNesting"
Title="MainWindow" Height="200" Width="300">
<local:UserControlLevel2>
<local:UserControlLevel2.ChildContent>
<StackPanel>
<TextBlock Text="Main Window Content Text"/>
</StackPanel>
</local:UserControlLevel2.ChildContent>
</local:UserControlLevel2>
</Window>
我是不是在尝试做一些不可能的事情?还是我对 ContentControl 和 DependencyProperties 做错了什么?我应该用不同的方法来看待这个问题吗?
有可能。系统无法解析 Binding
中的 ElementName
。解决方案是使用相对绑定。只需替换 UserControlLevel2 中的以下行即可完成:
<ContentControl Content="{Binding Path=ChildContent, RelativeSource={RelativeSource AncestorType={x:Type local:UserControlLevel2}}}"/>