# CreateChildPropertyGUI(VisualElement, SerializedProperty, SerializedProperty)

> Creates the GUI for a single attribute of the UXML serialized data.

## Definition

* **Type:** Method
* **Namespace:** [Unity.UIToolkit.Editor](/engine/6000.7/script-reference/unity/uitoolkit/editor.md)
* **Assembly:** UnityEditor

```csharp
protected virtual void CreateChildPropertyGUI(VisualElement container, SerializedProperty property, SerializedProperty childProperty)
```

### Parameters

**** (\[VisualElement]\(/engine/6000.7/script-reference/unityengine/uielements/visualelement)): The parent element to add the content to.**** (\[SerializedProperty]\(/engine/6000.7/script-reference/unityeditor/serializedproperty)): The serialized property that represents the UXML serialized data instance.**** (\[SerializedProperty]\(/engine/6000.7/script-reference/unityeditor/serializedproperty)): The serialized property for the attribute to draw.

### Remarks

The default implementation adds a [UxmlAttributeField](/engine/6000.7/script-reference/unity/uitoolkit/editor/uxmlattributefield.md) bound to `childProperty`. Override this method to draw specific attributes with a custom layout, and call the base method for the rest.

The following example draws specific attributes with custom layouts and action buttons.

### Examples

```csharp
// Override CreateChildPropertyGUI to render specific properties with custom layouts.
//
// This example targets an InfoPanel element with two string [UxmlAttribute] properties:
//   - "text": a freeform description rendered as a multiline TextField with a Clear button.
//   - "documentationUrl": a URL rendered as a single-line TextField with an Open button.
//
// Both fields use a UxmlAttributeFieldDecorator so they retain override and binding affordances.
// All other properties fall back to the default UxmlAttributeField rendering via the base class.
[CustomPropertyDrawer(typeof(InfoPanel.UxmlSerializedData))]
public class InfoPanelDrawer : UxmlSerializedDataPropertyDrawer
{
    protected override void CreateChildPropertyGUI(VisualElement container, SerializedProperty property, SerializedProperty childProperty)
    {
        switch (childProperty.name)
        {
            case "text":
                container.Add(BuildMultilineFieldWithClear(property, childProperty));
                break;

            case "documentationUrl":
                container.Add(BuildUrlFieldWithOpen(property, childProperty));
                break;

            default:
                base.CreateChildPropertyGUI(container, property, childProperty);
                break;
        }
    }

    // Builds a row with a multiline TextField inside a UxmlAttributeFieldDecorator and a Clear button.
    static VisualElement BuildMultilineFieldWithClear(SerializedProperty property, SerializedProperty childProperty)
    {
        // Cache the path and the object — both properties are references that may be recycled after
        // this method returns, so the button callback must not touch either one.
        string propertyPath = childProperty.propertyPath;
        SerializedObject serializedObject = property.serializedObject;

        VisualElement row = new VisualElement();
        row.style.flexDirection = FlexDirection.Row;

        UxmlAttributeFieldDecorator decorator = new UxmlAttributeFieldDecorator();
        TextField textField = new TextField(childProperty.displayName);
        textField.bindingPath = propertyPath;
        textField.multiline = true;
        textField.style.flexGrow = 1;
        decorator.Add(textField);
        row.Add(decorator);

        row.Add(new Button(() =>
        {
            SerializedProperty serializedProperty = serializedObject.FindProperty(propertyPath);
            if (serializedProperty != null)
            {
                serializedProperty.stringValue = string.Empty;
                serializedObject.ApplyModifiedProperties();
            }
        }) { text = "Clear" });

        return row;
    }

    // Builds a row with a single-line TextField inside a UxmlAttributeFieldDecorator and an Open button.
    static VisualElement BuildUrlFieldWithOpen(SerializedProperty property, SerializedProperty childProperty)
    {
        string propertyPath = childProperty.propertyPath;
        SerializedObject serializedObject = property.serializedObject;

        VisualElement row = new VisualElement();
        row.style.flexDirection = FlexDirection.Row;

        UxmlAttributeFieldDecorator decorator = new UxmlAttributeFieldDecorator();
        TextField textField = new TextField(childProperty.displayName);
        textField.bindingPath = propertyPath;
        textField.style.flexGrow = 1;
        decorator.Add(textField);
        row.Add(decorator);

        row.Add(new Button(() =>
        {
            SerializedProperty serializedProperty = serializedObject.FindProperty(propertyPath);
            if (serializedProperty != null && !string.IsNullOrEmpty(serializedProperty.stringValue))
                Application.OpenURL(serializedProperty.stringValue);
        }) { text = "Open" });

        return row;
    }
}
```
