- Home /
UIElements display:none not working properly
I'm getting some really strange behavior when setting the display-style of a button. The expected behavior is that the install button acts as if it doesn't exist (can be seen at end of gif) - it is invisible and removed from the layout. Setting the style inline or through a style sheet has the expected behavior, but is not dynamic (and is therefore not very useful). My code: C#:
var installButton = rootVisualElement.Q<Button>("plugin-install-button");
var removeButton = rootVisualElement.Q<Button>("plugin-remove-button");
var updateButton = rootVisualElement.Q<Button>("plugin-update-button");
installButton.style.display = pluginInstalled ? DisplayStyle.None : DisplayStyle.Flex;
removeButton.style.display = pluginInstalled ? DisplayStyle.Flex : DisplayStyle.None;
updateButton.style.display = pluginInstalled ? DisplayStyle.Flex : DisplayStyle.None;
UXML:
<engine:Button name="plugin-install-button" text="Install"/>
<engine:Button name="plugin-update-button" text="Update"/>
<engine:Button name="plugin-remove-button" text="Remove"/>
First, the button remains visible until I resize the window. The layout is still incorrect even after it dissappears. Calling MarkDirtyRepaint()
on either the buttons, their parents, or the root does nothing, and calling EditorWindow.Repaint()
also does nothing. The only way that I can get the layout to update correctly is by changing the display property in the UIElements Debugger to 'flex' and then back to 'none'. Note: I'm using Unity 2020.1.0b4
EDIT: I think that my problem may be caused by calling the C# code below from asynchronous code. (I think from another thread). This might be incorrect though, as using VisualElement.schedule
to effectively queue actions didn't solve the problem.
Hey @$$anonymous$$Davies, I don't think there's enough context to solve this issue -- could you share some more code? Is that C# code in your EditorWindow
class's OnEnable
? You mentioned async/threading?
The code is called in a callback method from System.Diagnostics.Process.Start(), or more specifically, in the callback for Process.Exited (which is run when the process has completed its task). In this case the process call is to run some git commands.
The original call to Process.Start is in the EditorWindow’s OnEnable.
Try running this async code in try/catch block, where catch uses Debug.LogException
. You may see hidden exception here.
Fortunately (or unfortunately for the future), I no longer have the code for it as I refactored it to not need to change the buttons this way. I think it's unlikely to be an exception, given that it correctly runs the code - the display property does change, it just doesn't seem to trigger a repaint or layout update. It's almost as if it's not detecting the change.
Unity throws exceptions when foreign thread calls !thread-safe functions,`Repaint` for example
+1
to what @andrew-lukasik said. Here's a $$anonymous$$imal demo -- if you create a basic UIElements editor window and add a simple async call like this...
public void OnEnable {
... // default stuff from Create -> UIElements -> Editor Window
root.Add(labelWithStyle);
Task.Run(() => HideLabel(labelWithStyle));
}
public void HideLabel(Label lbl)
{
try
{
Debug.Log("Starting sleep.");
System.Threading.Thread.Sleep(2000);
Debug.Log("Sleep complete.");
lbl.style.display = DisplayStyle.None;
}
catch (System.Exception e)
{
Debug.Log($"{e}");
}
}
... you'll get an Exception like so:
If you tried to modify the layout, for example using rootVisualElement.Clear()
, you'd get a similar exception -- UnityEngine.UnityException: YGNodeRemoveChild can only be called from the main thread.
Your answer
Follow this Question
Related Questions
Initialising List array for use in a custom Editor 1 Answer
How to make an Editor Window with a border 1 Answer
Text in custom editor is displayed/rendered with boxes around characters... 2 Answers
Is there a way to stylize EditorGUI.ObjectField? 0 Answers
Casting browser window (or any window) inside Unity editor? Or a transparent Unity app? 0 Answers