Wpf 自定义控件充当允许XAML中的子级的页

Wpf 自定义控件充当允许XAML中的子级的页,wpf,wpf-controls,custom-controls,wrappanel,Wpf,Wpf Controls,Custom Controls,Wrappanel,我实际上有两个问题: 如何修改从仅包含一个子项(例如Page或ContentControl)的FrameworkElement继承的自定义控件,使其包含多个子项(如面板)?这可以从类定义中完成吗 如何将自定义控件的子控件绑定到自定义控件模板中定义的面板对象(例如WrapPanel) 我甚至不确定这是否可行,但我想创建一个行为类似于页面的自定义控件,或者甚至可以从页面继承,但允许我在XAML中输入子控件。例如,我希望生成自定义控件的XAML如下所示: <CustomPage CustomAt

我实际上有两个问题:

  • 如何修改从仅包含一个子项(例如Page或ContentControl)的FrameworkElement继承的自定义控件,使其包含多个子项(如面板)?这可以从类定义中完成吗

  • 如何将自定义控件的子控件绑定到自定义控件模板中定义的面板对象(例如WrapPanel)

  • 我甚至不确定这是否可行,但我想创建一个行为类似于页面的自定义控件,或者甚至可以从页面继承,但允许我在XAML中输入子控件。例如,我希望生成自定义控件的XAML如下所示:

    <CustomPage CustomAttribute="blah">
        <TextBox/>
        <TextBlock Text="hehe"/>
        <Label Content="ha!"/>
    </CustomPage>
    
    <Style TargetType="{x:Type CustomPage}">
        <Style.Setters>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type CustomPage}">
                        <WrapPanel/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style.Setters>
    </Style>
    
    
    
    我想定义包装面板显示子对象的样式。大概是这样的:

    <CustomPage CustomAttribute="blah">
        <TextBox/>
        <TextBlock Text="hehe"/>
        <Label Content="ha!"/>
    </CustomPage>
    
    <Style TargetType="{x:Type CustomPage}">
        <Style.Setters>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type CustomPage}">
                        <WrapPanel/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style.Setters>
    </Style>
    
    
    
    我会用ContentPresenter替换WrapPanel,但我希望ContentPresenter的行为像WrapPanel一样


    我希望这足够具体。

    使用ItemsControl,您实际上已经可以做您想要的事情了

        <ItemsControl>
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.Items>
                <TextBox/>
                <TextBlock Text="hehe"/>
                <Label Content="ha!"/>
            </ItemsControl.Items>
        </ItemsControl>
    
    
    
    希望有帮助


    编辑:您可以使用上面的ItemsControl作为页面中的根元素来获得页面的功能。

    谢谢您,Murkaeus。你让我走对了方向

    最后,我创建了一个从页面继承的自定义控件,并为其定义了ContentProperty。这显然覆盖了基类的ContentProperty。这也适用于任何控件类型。这是我的密码:

        [ContentProperty("Children")]
        class CustomPage : System.Windows.Controls.Page
        {
            ObservableCollection<UIElement> children = new ObservableCollection<UIElement>();
            public ObservableCollection<UIElement> Children { get { return children; } set { children = value; } }
        }
    
    [ContentProperty(“子项”)]
    类CustomPage:System.Windows.Controls.Page
    {
    ObservableCollection子项=新的ObservableCollection();
    公共observeCollection子项{get{return Children;}set{Children=value;}}
    }
    
    然后,我在Themes/Generic.xaml文件中为我的控件定义了模板,其中包含一个使用我的自定义ContentProperty作为源的ItemsControl:

        <Style TargetType="local:CustomPage">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate>
                        <ItemsControl ItemsSource="{Binding Children,
                                                    RelativeSource={RelativeSource TemplatedParent}}">
                            <ItemsControl.ItemsPanel>
                                <ItemsPanelTemplate>
                                    <WrapPanel/>
                                </ItemsPanelTemplate>
                            </ItemsControl.ItemsPanel>
                        </ItemsControl>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    
    
    
    我希望这能帮助其他正在寻找相同问题解决方案的人。再次感谢你的帮助,穆凯乌斯

    编辑:我应该警告大家,如果使用这种方法,由于某种原因,所有数据绑定都会丢失,我通过进一步的实验发现了这一点。我最终放弃了,只指定了一个面板作为自定义页面对象的子对象