【问题标题】:Custom control acting as Page allowing children in XAML自定义控件充当页面,允许 XAML 中的子级
【发布时间】:2013-05-02 23:12:10
【问题描述】:

其实我有两个问题:

  1. 如何修改从仅包含一个子项(例如 Page 或 ContentControl)的 FrameworkElement 继承的自定义控件,以便它包含多个子项(例如 Panel)?这可以从类定义中完成吗?

  2. 如何将自定义控件的子级绑定到自定义控件模板中定义的 Panel 对象(例如 WrapPanel)?

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

<CustomPage CustomAttribute="blah">
    <TextBox/>
    <TextBlock Text="hehe"/>
    <Label Content="ha!"/>
</CustomPage>

我想定义 WrapPanel 显示子项的样式。像这样的:

<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。

我希望这足够具体。

【问题讨论】:

    标签: wpf wpf-controls custom-controls wrappanel


    【解决方案1】:

    您实际上可以使用 ItemsControl 完全按照您的意愿行事。

        <ItemsControl>
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.Items>
                <TextBox/>
                <TextBlock Text="hehe"/>
                <Label Content="ha!"/>
            </ItemsControl.Items>
        </ItemsControl>
    

    希望有帮助

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

    【讨论】:

      【解决方案2】:

      谢谢你,穆尔凯厄斯。你让我朝着正确的方向前进。

      最后,我创建了一个继承自 Page 的自定义控件,并为其定义了一个 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; } }
          }
      

      然后,我在 Themes/Generic.xaml 文件中为我的控件定义了模板,其中 ItemsControl 使用我的自定义 ContentProperty 作为源:

          <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>
      

      我希望这对正在寻找解决同一问题的其他人有所帮助。再次感谢 Murkaeus 的帮助!

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-01-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-10-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多