基本上,我希望我的UserControl能够接受一种ItemsControl类型,以便我的XAML看起来像这样:
<my:MyControl DataContext="{Binding InnerViewModel}">
<ItemsControl ... />
</my:MyControl>
那样,MyControl会显示自定义Items控件和其他控件吗?
答案 0 :(得分:6)
首先注意几点:
UserControl
是一种ContentControl
。这意味着您无法将子元素传递给UserControl。您可以覆盖内容,但这对于您想要完成的内容来说毫无结果。Decorator
类。ItemsControl
类。所以,基本上你做错了。话虽这么说,有几种方法可以实现你想要的。您可以简单地使用ItemsControl并使用您自己的模板覆盖模板。您还可以创建一个继承自ItemsControl或Decorator的CustomControl。
覆盖模板(作为样式)将是更简单的方法,所以我的建议就是这样做,除非你非常精通如何正确创建WPF自定义控件
如果您选择使用自定义控件,看起来您可能希望将其作为装饰器(只是猜测您需要一个孩子)。令人讨厌的部分是,要真正创建一个写得很好的WPF自定义控件,你必须拥有一些非常好的技能。例如,Border
是一种包含少量DependencyProperty
属性的装饰器。该模板附带了PresentationFramework.dll(我认为),因此它具有一些默认的外观。边框(自定义控件)不是 难以编写。当你想要实际拥有交互逻辑时,非常烦人的是什么。您需要进行检查和平衡以确保从模板中检索控件引用。然后,只有这样,如果引用不为null,你可以继续你的逻辑。基本上,假设您编写了一种自定义控件,它有2个按钮来执行逻辑,并且您提供了一个默认模板,其中按钮被命名为“按钮1”和“按钮2”。你不能只从模板中拉出按钮1和按钮2,并期望它们在那里;有人可以轻松覆盖您的默认模板并删除按钮1和按钮2,使您的自定义控件无用(非常多)。如果您编码时没有考虑到这些情况,那么可怕的是什么。你的自定义控件会遇到NullReferenceException
。更不用说你必须连接以允许命令绑定PER按钮,你还应该为每个按钮提供routedevent。基本上,自定义控件可能对您想要做的事情(可能)有点过多。
我可能是错的,你可能超级熟练并知道如何制定自定义控件。或者,更好的是,您可能只想通过一种简单的方式来装饰您的ItemsControl,并在其顶部添加横幅?我不知道,但我相信你会这样做:)。
总的来说,我将介绍如何覆盖ItemsControl模板。这是一个示例:
<Window x:Class="Sample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="640" Height="480">
<Window.Resources>
<Style x:Key="ItemsControlStyle1" TargetType="{x:Type ItemsControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ItemsControl}">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
<StackPanel Orientation="Vertical">
<TextBlock Text="A HEADER!" />
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</StackPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid x:Name="LayoutRoot">
<ItemsControl Style="{DynamicResource ItemsControlStyle1}" />
</Grid>
</Window>