String in custom element is null

using UnityEngine;
using UnityEngine.UIElements;

[UxmlElement]
public partial class TestVisualElement : VisualElement
{
    [UxmlAttribute]
    public string TestString { get; set; }

    public TestVisualElement()
    {
        Debug.Log(TestString);
    }
}

9845655--1416984--upload_2024-5-20_23-16-42.png


Why?

The value is applied after the element is constructed, there’s no way we could do it before. You can use the property setter method to know when its set.

Ok this seems to work

using UnityEngine;
using UnityEngine.UIElements;

[UxmlElement]
public partial class TestVisualElement : VisualElement
{
    [UxmlAttribute]
    public string TestString { get; set; }

    public TestVisualElement()
    {
        RegisterCallback<AttachToPanelEvent>(OnAttachToPanel);
    }

    void OnAttachToPanel(AttachToPanelEvent evt)
    {
        Debug.Log(TestString);
    }
}

9845730--1417005--upload_2024-5-20_23-55-54.png

When I use this custom element directly in UI Document it works fine but if I make a template from it and use this template inside the document it returns null again

Ok seems like using setter works fine in all cases, thanks

Got new problem. The property gets reseted for some reason in this code:

[UxmlElement]
public partial class KeyBindingView : VisualElement
{
    [UxmlAttribute]
    public string ActionName
    {
        get => _actionName;
        set
        {
            _actionName = value;
            Debug.Log("PROP: " + _actionName);
        }
    }

    private string _actionName;

    private Label KeyBindingNameLabel;
    private Button KeyBindingPrimaryActionButton;
    private Button KeyBindingSecondaryActionButton;

    public void Initialize()
    {
        Debug.Log("INIT");
        KeyBindingNameLabel = this.Q<Label>("key-binding__name-label");
        KeyBindingPrimaryActionButton = this.Q<Button>("key-binding__action-button-primary");
        KeyBindingSecondaryActionButton = this.Q<Button>("key-binding__action-button-secondary");

        InputAction action = InputSystem.actions.FindAction(ActionName);

        KeyBindingNameLabel.text = ActionName;
        KeyBindingPrimaryActionButton.text = action.bindings[0].ToDisplayString();
        KeyBindingSecondaryActionButton.text = action.bindings[0].ToDisplayString();
    }
}


Thats normal, it resets values in the UI Builder.
You should adjust your code to expect a null string or change the default value for _actionName.
Maybe change it to private string _actionName = "";

I’m not sure I understand how private string _actionName = ""; should help.
I want to configure different strings for each instance of KeyBindingTemplate but it resets all of them to value of _actionName.

The UI Builder will set all the attributes to their default values. The default value for ActionName is currently null. Instead of setting it to “” you would be better checking if the value is null or empty in Initialize and not calling InputSystem.actions.FindAction if it is.

I mean, yeah, there will be no error if I check for null or empty but property is initialized with configured in UIBuilder string and after that gets reseted to default value. So at the end all instances reseted to whatever _actionName is.
This is what I have in Builder:
9849330--1417893--upload_2024-5-22_18-16-58.png
It’s properly initialized at start
9849330--1417896--upload_2024-5-22_18-17-25.png
After that it gets reseted without calling property setter
9849330--1417902--upload_2024-5-22_18-19-44.png

I think it’s a bug or I don’t know something about templates. My uxml structure looks like this:
9856578--1419537--upload_2024-5-27_3-6-46.png
Everything is fine but if I give SettingsWindow.uxml template some name all properties in custom controls inside it will fail to initialize.
Without name:
9856578--1419540--upload_2024-5-27_3-9-53.png
With name:
9856578--1419543--upload_2024-5-27_3-10-50.png9856578--1419546--upload_2024-5-27_3-11-13.png
What could be the reason for this behavior?

Made bug report just in case (IN-77201)

Just got update that this bug is fixed in 6000.0.7f1

Hi! This is a bit of a gravedig but it looks like I am facing the same issue in Unity 6000.0.51f1 (which I downloaded yesterday while trying to fix this)

I have this LocalizedButton component that has a LocalizationKey attribute, so that the text of the button is pulled from the localization tables.

I previously implemented it with UxmlFactory/UxmlTraits and it worked just fine, but now I decided to try and migrate it to the new UxmlElement/UxmlAttribute approach. The button mostly works fine but when I open the UI Builder window and select this button, the text becomes empty. Upon reopening the UI Builder or running the game the text shows up properly again. This bug makes it inconvenient to work with the UI builder and I thought maybe I’m doing something wrong.

Here’s the code of the button:

    [UxmlElement]
    public partial class LocalizedButton : Button
    {
        // [Preserve]
        // public new class UxmlFactory : UxmlFactory<LocalizedButton, UxmlTraits> { }
        //
        // [Preserve]
        // public new class UxmlTraits : LocalizableUxmlTraits { }

        [UxmlAttribute]
        public string LocalizationKey
        {
            get => _localizationKey;
            set
            {
                _localizedString.TableEntryReference = value;
                _localizationKey = value;
            }
        }

        private string _localizationKey = "defaultValue";

        private readonly LocalizedString _localizedString;
 
        public LocalizedButton()
        {
            _localizedString = new LocalizedString(LocalizationSettings.StringDatabase.DefaultTable, string.Empty);
            _localizedString.StringChanged += str => text = str;
        }
    }

And screenshots from UI builder:


The text is a UXML Attribute, so it will be replaced with the empty string when the element is synced by the UI Builder. Changing other UXML Attributes can create unpredictable behaviour in the builder.
If you want to control the text attribute you should either use a data binding or override the text attribute. See MyOverrideDrawerAttribute - Unity - Scripting API: UxmlAttributeAttribute

The Localization package already has data binding support. I recommend using that:

Thanks for the reply!
I am not sure how I would apply MyOverrideDrawerAttribute here since those PropertyAttributes that you linked seemingly only affect how the UI builder draws its own attribute editor sidebar.

But nonetheless, I made it work with the localization package’s data binding support so thanks for that!