如何修改ControlTemplate以将项直接添加到我的自定义控件

时间:2012-06-14 15:14:04

标签: wpf wpf-controls custom-controls control-template

我为自定义控件定义了以下控件模板。

<ControlTemplate TargetType="{x:Type local:CustomControl}">
    <Grid x:Name="MainGrid">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>
        <local:CustomPanel x:Name="MyCustomPanel" Grid.Column="0" />
        <ScrollBar Grid.Column="1" Width="20" />
    </Grid>
</ControlTemplate>

这里CustomPanel派生Form类。现在我不能像这样直接将项目添加到我的CustomControl

<local:CustomControl x:Name="CControl" Grid.Row="1">
    <Button/>
    <Button/>
    <Button/>
</local:CustomControl>

如何直接从XAML将项目添加到我的自定义控件中?

2 个答案:

答案 0 :(得分:3)

在CustomControl上使用[ContentProperty( PropertyName )]

并且:确保将content属性初始化为空列表(不得为null)。

E.g:

[ContentProperty("Items")]
public class CustomControl : UserControl
{

    public static readonly DependencyProperty ItemsProperty =
        DependencyProperty.Register("Items", typeof(UIElementCollection), typeof(CustomControl), new UIPropertyMetadata(null)));

    public UIElementCollection Items     
    {     
        get { return (UIElementCollection) GetValue(ItemsProperty); }     
        set { SetValue(ItemsProperty, value); }     
    }   

    public CustomControl()
    {
        Items = new UIElementCollection();
    }

}

重要提示:不要在依赖项属性注册中创建空集合,即不要使用它:

... new UIPropertyMetadata(new UIElementCollection())

这被认为是不好的做法,因为你会无意中创建一个单例集合。有关详细信息,请参阅Collection-Type Dependency Properties

答案 1 :(得分:1)

这是一个示例控件,允许您以您追求的方式直接添加内容。

这里感兴趣的行是MyCustomControl类顶部的属性,它告诉XAML编辑器应该放置任何直接添加的内容的属性。

在XAML代码中,重要的一行是ItemsControl,它绑定到Items属性,实际上显示了每个项目。

C#

[ContentProperty("Items")]
public class MyCustomControl : Control
{
    public ObservableCollection<Object> Items
    {
        get { return (ObservableCollection<Object>)GetValue(ItemsProperty); }
        set { SetValue(ItemsProperty, value); }
    }

    public static readonly DependencyProperty ItemsProperty =
        DependencyProperty.Register("Items", typeof(ObservableCollection<Object>), typeof(MyCustomControl), new UIPropertyMetadata(new ObservableCollection<object>()));        
}

XAML

<Style TargetType="{x:Type local:MyCustomControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:MyCustomControl}">
                <ItemsControl ItemsSource="{TemplateBinding Items}"  />
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<local:MyCustomControl>
    <Button />
    <Button />
</local:MyCustomControl>