我的任务
创建一个UserControl
,它应该能够包含在WPF中可用的任何可视子元素,这些子元素显示在UserControl
的子容器中。
我的问题
我无法正确地将子元素显示在我的容器中,我尝试了几种方法,但没有找到可以在设计器中正常工作的方法。我也尝试使用ContentControl
,但没有显示任何内容。
我的尝试
首先,我找到了此链接并尝试了一些变化。我成功地在正确的容器中显示了内容,但是这在设计器中不起作用,因为内容属性是私有设置的,设计器想要覆盖它。将所有内容放在XAML中可以工作,但是在与设计师合作时不太好。这是我最喜欢的方式。
在此之后,我尝试通过将ContentControl
的Content
属性绑定到UIElementCollection
类型的可绑定属性来使用它。这种方法在设计器中不会引发任何错误,但我必须承认我从未在我的容器中看到任何控件(例如Button
),它保持为空但已添加了子元素。
结论
经过几个小时的寻找快速简单的解决方案,我决定在这里寻求帮助。我有点失望。如果Microsoft能够在MSDN中提供示例,那将非常有帮助。
我相信一定有一个简单的方法可以实现这一点。
当前情况
由于Andrei Gavrila和jberger的帮助,我成功创建了一个显示内容的节点(请参见下面的代码),但仍然存在两个问题: - 没有设计器支持 - 边框(参见XAML)在设计器中不显示,在应用程序运行时也不显示,甚至没有边距。
public class NodeContent : ContentControl
{
static NodeContent()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(NodeContent), new FrameworkPropertyMetadata(typeof(NodeContent)));
}
}
public partial class Node : UserControl, INotifyPropertyChanged
{
UIElementCollection _Elements;
public event PropertyChangedEventHandler PropertyChanged;
public UIElementCollection NodeContent
{
get { return _Elements; }
set
{
_Elements = value;
OnPropertyChanged("NodeContent");
}
}
public Node()
{
InitializeComponent();
NodeContent = new UIElementCollection(NodeContentContainer, this);
}
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
Node-Xaml:
<UserControl x:Class="Pipedream.Nodes.Node"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="216" d:DesignWidth="174" Background="Transparent" Name="NodeControl" xmlns:my="clr-namespace:Pipedream.Nodes">
<Border BorderThickness="1" CornerRadius="20" BorderBrush="Black" Background="White">
<Grid>
<my:NodeContent x:Name="NodeContentContainer" Margin="20" Content="{Binding Source=NodeControl, Path=NodeContent}" />
</Grid>
</Border>
</UserControl>
通用 Xaml:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Pipedream.Nodes">
<Style TargetType="{x:Type local:NodeContent}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:Node}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
ItemsControl
和ItemsPresenter
替换为ContentControl
和ContentPresenter
。 - Jake BergerUserControl
? - Jake Berger