【发布时间】:2012-02-24 01:18:06
【问题描述】:
我的任务
创建一个UserControl,它应该能够包含 WPF 中可用的任何可视子项,子项显示在一个容器中,该容器是UserControl 的子项。
我的问题
我无法让孩子在我的容器中正确显示,我尝试了多种方式,但没有找到适合设计器的方式。我也尝试使用ContentControl,但没有显示任何内容。
我的方法
首先我找到了this 链接,并尝试了一些变化。我设法在正确的容器中显示内容,但它在设计器中不起作用,因为内容属性是设置私有的并且设计器想要覆盖它。将所有内容都放在 XAML 中是可行的,但这在与设计人员合作时并不好。这可能是最喜欢的方式。
在此之后,我尝试通过将 Content-property 绑定到 UIElementCollection-type 的可绑定属性来使用 ContentControl。这种方法不会在设计器中引发任何错误,但我必须承认我在容器中从未看到任何控件(例如 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));
}
}
}
节点 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>
【问题讨论】:
-
或者,也许,也许,您可以尝试使用 ControlTemplate 来转换面板,而不是创建新的控件?
-
@deerchao 我真的需要一个自己的用户控件。不过谢谢你的建议。
-
在“我的方法”下,第 2 段似乎自相矛盾:“它保持空白,但添加了孩子。”..?
-
@jberger 哦,这仅仅意味着没有孩子可见。 :-)
-
您定义了什么模板/主题来显示自定义
ContentControl?
标签: c# wpf user-controls wpf-controls