I've build the UI system using the Model View design pattern.
It means that the Widgets composing the UI are considered as Views, which means that they don't handle any logic but are just a way to display datas. The class which handle the logic behind the UI is the Model (It is often one of the ActorComponents which handles a specific gameplay feature, like the Inventory).
Once you have properly linked a View to its Model, you are assured that everything will be displayed on the View.
The Model notify the View that it needs to update it Visual using the EventDisplayer system. Doing that, the View need to know about the Model, but the Model doesn't need to know anything about the View, which avoid us to have many Interfaces for the Models. With this system we just need to tell the EventDispatcher that something has changed in the model.
You link the Model with the View by calling the SetModel() function which is inside the View.
Here is the SetModel() function of the QuickAccessInventoryPanel Widget.
The CreateSlots() function will simply initialise the default visual. Sometime I used a function called InitVisual() here.
And here are the LinkToModel() and UnlinkToModel() events. As you can see, we use the OnInventoryContentChanged and the OnInventorySlotModified of the Model (The model is a QuickAccessInventory here).
Note that it is a good practice to unlink event dispatchers when you destroy the visual. You can do it by calling SetModel() with no parameter for Model. Thisremove the reference to the model and call the UnlinkToModel() event.