使用 XAML 创建 WPF UserControl,以便我可以在其中嵌套子控件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14316982/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 07:00:48  来源:igfitidea点击:

Create WPF UserControl with XAML so that I can nest children controls inside

wpfxamldata-bindingwpf-controls

提问by heltonbiker

I am trying to create a "titled block" UserControl in WPF/XAML, with the following behaviour:

我正在尝试在 WPF/XAML 中创建一个“标题块”UserControl,具有以下行为:

  • The control itself is a Border containing a DockPanel. The DockPanel contains a top-aligned "title" TextBlock, and the rest of this DockPanel should be the "children widget area".
  • 控件本身是一个包含 DockPanel 的 Border。DockPanel 包含一个顶部对齐的“标题”TextBlock,这个 DockPanel 的其余部分应该是“子部件区域”。

The control declaration is like this:

控制声明是这样的:

<Border x:Name="LayoutRoot" Background="#4C000000" CornerRadius="10" Padding="10">
    <DockPanel>
        <TextBlock Text="Some Title" DockPanel.Dock="Top" />
    </DockPanel>
</Border>

And the intended usage is like this:

预期用途是这样的:

<Grid x:Name="LayoutRoot" Background="White">
    <local:Bloco Height="100" Width="100" Title="Other Title">
        <local:Bloco Title="Yet other title" />
    </local:Bloco>
</Grid>

To render something like this:

要渲染这样的东西:

enter image description here

在此处输入图片说明

The actual current rendering is invalid, though. The problems are:

但是,实际的当前渲染是无效的。问题是:

  • I don't know (and didn't found it via searching) how to make the control have a "children container" where I could add children via direct nesting in the XAML;
  • I don't know how to bind a different title for each instance of the user control, be it via XAML attributes or bindings (preferrable), be it via code behind. Writing the code as above creates invalid xaml code, which is unsurprising since the "Title" attribute does not exist yet.
  • 我不知道(也没有通过搜索找到它)如何让控件有一个“子容器”,我可以通过在 XAML 中直接嵌套来添加子容器;
  • 我不知道如何为用户控件的每个实例绑定不同的标题,无论是通过 XAML 属性还是绑定(首选),还是通过背后的代码。编写上述代码会创建无效的 xaml 代码,这并不奇怪,因为“Title”属性尚不存在。

Thanks for reading!

谢谢阅读!

回答by chameleon86

  1. You may create control that inherits from ContentControl and add template for it
  2. If you want get access to your custom properties in xaml as attributes you need register it as DependencyProperty (see enter link description here)
  1. 您可以创建继承自 ContentControl 的控件并为其添加模板
  2. 如果您想访问 xaml 中的自定义属性作为属性,您需要将其注册为 DependencyProperty(请参阅此处输入链接描述

回答by rhe1980

Generic usercontrol:

通用用户控件:

XAML:

XAML:

<UserControl x:Class="WpfControlLibrary.GenericUserControl"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WpfControlLibrary"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300" x:Name="Control">
<UserControl.Resources>
    <Style TargetType="{x:Type local:GenericUserControl}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:GenericUserControl}">
                    <Grid Background="{Binding Background, ElementName=Control}">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="5"></RowDefinition>
                            <RowDefinition Height="20"></RowDefinition>
                            <RowDefinition Height="*"></RowDefinition>
                            <RowDefinition Height="5"></RowDefinition>
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="5"/>
                            <ColumnDefinition Width="*"/>
                            <ColumnDefinition Width="5"/>
                        </Grid.ColumnDefinitions>
                        <TextBlock Grid.Column="1" Grid.Row="1" Text="{Binding Title, ElementName=Control}"/>
                        <ContentPresenter Grid.Column="1" Grid.Row="2"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</UserControl.Resources>

Code behind:

后面的代码:

namespace WpfControlLibrary
{
   public partial class GenericUserControl
   {
      public string Title
     {
        get { return (string)GetValue(TitleProperty); }
        set { SetValue(TitleProperty, value); }
     }

     public static readonly DependencyProperty TitleProperty =
      DependencyProperty.Register("Title", typeof(string), typeof(GenericUserControl), new PropertyMetadata(string.Empty));

public GenericUserControl()
     {
        InitializeComponent();
     }
   }
}

And than use the user control like this:

而不是像这样使用用户控件:

    <wpfControlLibrary:GenericUserControl Title="Other Title" Background="LightGray">
       <wpfControlLibrary:GenericUserControl Title="Yet Another Title" Background="Gray"/>
</wpfControlLibrary:GenericUserControl>