Container Vs CompositeDrawable
Both Container and CompositeDrawable can be inherited from to contain a collection of Drawables, but they have different uses.
CompositeDrawable
abstract class CompositeDrawable : Drawable
A CompositeDrawable is an abstract class that provides functionality to group one or more internal child Drawables into a single parent Drawable. Important to remember is that CompositeDrawable does not expose public methods to dynamically add internal children, this should happen inside a subclass of CompositeDrawable.
Some usages of CompositeDrawable by the framework are:
DelayedLoadWrapper: A wrapping drawable that waits for a specified amount of time after becoming visible before loading its child. Used as children forScrollContainers to not draw every child at once.ModelBackedDrawable<T>: An abstract class which holds a model and recreates its child drawable if said model changes.GridContainer: Contains multipleDrawables which are laid out in a pre-determined grid. AContainercannot be used here because children need to be assigned to a specific slot (Containercontains a single, dynamic collection).
Container
class Container<T> :
CompositeDrawable,
IContainerEnumerable<T>,
IContainerCollection<T>,
ICollection<T>,
IReadOnlyList<T>
where T : Drawable
A Container is a basic implementation of CompositeDrawable which holds a collection of children, accessed through the IReadOnlyList<T> Children property or through methods such as Add, AddRange, Remove, Clear, etc. The class can be inherited from to provide customized functionality, such as automatic positioning and sizing of children.
Container contains a virtual property Content, which is a reference to the container whose InternalChildren will be used for Children. By default, this is a reference to itself meaning it serves like a CompositeDrawable with Add/Remove methods, but overriding this allows for adding a set of Drawables to the underlying CompositeDrawable.InternalChildren that won't show up in Children, such as scroll bars or backgrounds. This is how the framework creates containers such as ScrollContainer which draws additional elements not explicitly added to Children.
As a simple container
A Container can be used to simply group a set of Drawables. Transformations applied to it will be passed down to its children.
[BackgroundDependencyLoader]
private void Load()
{
Drawable drawable;
Add(drawable = new Checkerboard(3)
{
Size = new Vector2(200),
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
});
AddSliderStep("Scale X", -2f, 2f, 1f, val => drawable.Scale = new Vector2(val, drawable.Scale.Y));
AddSliderStep("Scale Y", -2f, 2f, 1f, val => drawable.Scale = new Vector2(drawable.Scale.X, val));
AddSliderStep("Shear X", -2f, 2f, 0f, val => drawable.Shear = new Vector2(val, drawable.Shear.Y));
AddSliderStep("Shear Y", -2f, 2f, 0f, val => drawable.Shear = new Vector2(drawable.Shear.X, val));
AddSliderStep("Rotate", -360f, 360f, 0f, val => drawable.Rotation = val);
}
Overriding Content
A basic example of overriding the Content property to add extra Drawawbles to a container follows:
/// <summary>
/// A Container with a blue background.
/// </summary>
public class BlueBackgroundContainer : Container
{
private readonly Container _contentContainer;
protected override Container<Drawable> Content => _contentContainer;
public BlueBackgroundContainer()
{
_contentContainer = new Container {AutoSizeAxes = Axes.Both};
}
[BackgroundDependencyLoader]
private void Load()
{
InternalChildren = new Drawable[]
{
_contentContainer,
// a blue background, filling its parent and drawn behind everything else
new Box
{
Colour = Color4.RoyalBlue,
RelativeSizeAxes = Axes.Both,
Depth = 1,
},
};
}
}
Specialized Layout
See Custom Layouts.