【问题标题】:How to modify ControlTemplate to add items directly to my custom control如何修改 ControlTemplate 以将项目直接添加到我的自定义控件
【发布时间】:2012-06-14 15:14:04
【问题描述】:

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

<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 派生自 Panel 类。现在我不能像这样直接将项目添加到我的 CustomControl 中

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

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

【问题讨论】:

  • 自定义面板是否有未设置的内容属性?
  • @GoldkinG:我已经更新了我的答案。

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


【解决方案1】:

在您的 CustomControl 上使用 [ContentProperty(PropertyName)]

并且:确保内容属性初始化为一个空列表(不能是null)。

例如:

[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

【讨论】:

    【解决方案2】:

    这是一个示例控件,可让您以自己喜欢的方式直接添加内容。

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

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

    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>
    

    【讨论】:

    • 如果 C# 属性看起来有点冗长,不要忘记它是一个代码片段,只需键入 propdp 并按两次 Tab。
    猜你喜欢
    • 1970-01-01
    • 2015-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-17
    • 2023-04-02
    • 1970-01-01
    相关资源
    最近更新 更多