namespace Eto.Forms;
///
/// Base for all visual UI elements
///
///
/// All visual user interface elements should inherit from this class to provide common functionality like binding,
/// load/unload, and common events.
///
[sc.TypeConverter(typeof(ControlConverter))]
public partial class Control : BindableWidget, IMouseInputSource, IKeyboardInputSource, ICallbackSource
{
///
/// Gets or sets a value indicating the UI is being shown in a designer preview, e.g. to supply sample data.
///
///
/// Set by the designer when it starts; applications should not need to set this.
///
public static bool IsDesignMode { get; set; }
// shared by the xaml and json readers so a user control in either format inherits its parent's design data
[ThreadStatic]
static int designLoadDepth;
internal static void BeginDesignLoad() => designLoadDepth++;
internal static void EndDesignLoad() => designLoadDepth--;
/// True while loading the outermost file in design mode, where d:DataContext applies.
internal static bool IsDesignRootLoad => IsDesignMode && designLoadDepth == 1;
///
/// Gets the handler for the widget, ensuring the current thread is the UI thread
///
/// The handler object for this control
protected new IHandler Handler
{
get
{
Application.Instance?.EnsureUIThread();
return (IHandler)base.Handler;
}
}
static readonly object GesturesKey = new object();
///
/// Gets the gestures attached to this control.
///
public Collection Gestures => Properties.Create(GesturesKey, () => new GestureCollection(this));
class GestureCollection : Collection
{
public GestureCollection(Control control)
{
this.control = control;
}
private readonly Control control;
protected override void InsertItem(int index, Gesture item)
{
control.Handler.AddGesture(item);
item.Control = control;
base.InsertItem(index, item);
}
protected override void ClearItems()
{
foreach (var item in this)
{
item.Control = null;
}
control.Handler.ClearGestures();
base.ClearItems();
}
protected override void RemoveItem(int index)
{
var item = this[index];
control.Handler.RemoveGesture(item);
item.Control = null;
base.RemoveItem(index);
}
protected override void SetItem(int index, Gesture item)
{
var oldItem = this[index];
control.Handler.AddGesture(item);
control.Handler.RemoveGesture(oldItem);
oldItem.Control = null;
item.Control = control;
base.SetItem(index, item);
}
}
///
/// Gets a value indicating that the control is loaded onto a form, that is it has been created, added to a parent, and shown
///
///
/// The method sets this value to true after cascading to all children (for a )
/// and calling the platform handler's implementation. It is called after adding to a loaded form, or when showing a new form.
///
/// The method will set this value to false when the control is removed from its parent
///
public bool Loaded
{
get => GetState(StateFlag.Loaded);
private set => SetState(StateFlag.Loaded, value);
}
///
/// Gets a value indicating that has been raised since the control was last loaded.
///
///
/// A control is before it gets its LoadComplete, so this is used to ensure LoadComplete is
/// only raised once, e.g. when a child is added to a container that is loaded but hasn't had LoadComplete yet.
///
internal bool IsLoadComplete
{
get => GetState(StateFlag.LoadComplete);
private set => SetState(StateFlag.LoadComplete, value);
}
///
/// Gets an enumeration of controls that are in the visual tree.
///
///
/// This is used to specify which controls are contained by this instance that are part of the visual tree.
/// This should include all controls including non-logical Eto controls used for layout.
///
/// The visual controls.
public virtual IEnumerable VisualControls => Handler.VisualControls;
///
/// Gets or sets a user-defined object that contains data about the control
///
///
/// A common use of the tag property is to store data that is associated with the control that you can later
/// retrieve.
///
public object Tag
{
get { return Properties.Get(TagKey); }
set { Properties[TagKey] = value; }
}
///
/// Gets the logical parent control.
///
///
/// When the control is part of the visual tree ( is true), this returns the logical parent that contains this control.
/// Otherwise this is the same as .
///
/// The logical parent.
public Container LogicalParent
{
get
{
if (IsVisualControl)
{
var foundVisual = false;
foreach (var parent in Parents.OfType())
{
if (!foundVisual && parent.GetState(StateFlag.IsVisualControl))
foundVisual = true;
else
return parent;
}
}
return Parent;
}
}
///
/// Gets a value indicating this is part of the visual tree.
///
/// true if is visual control; otherwise, false .
public bool IsVisualControl
{
get => GetState(StateFlag.IsVisualControl, StateFlag.IsVisualControlHasValue) ?? Parent?.IsVisualControl ?? false; // traverse up logical tree
internal set => SetState(StateFlag.IsVisualControl, StateFlag.IsVisualControlHasValue, value);
}
static readonly object TagKey = new object();
#region Events
///
/// Event identifier for handlers when attaching the event
///
public const string SizeChangedEvent = "Control.SizeChanged";
///
/// Occurs when the size of the control is changed.
///
public event EventHandler SizeChanged
{
add { Properties.AddHandlerEvent(SizeChangedEvent, value); }
remove { Properties.RemoveEvent(SizeChangedEvent, value); }
}
///
/// Raises the event.
///
/// Event arguments
protected virtual void OnSizeChanged(EventArgs e)
{
Properties.TriggerEvent(SizeChangedEvent, this, e);
}
///
/// Event identifier for handlers when attaching the event.
///
public const string KeyDownEvent = "Control.KeyDown";
///
/// Occurs when a key has been pressed and is down
///
///
public event EventHandler KeyDown
{
add { Properties.AddHandlerEvent(KeyDownEvent, value); }
remove { Properties.RemoveEvent(KeyDownEvent, value); }
}
///
/// Raises the event.
///
/// Key event arguments
protected virtual void OnKeyDown(KeyEventArgs e)
{
Properties.TriggerEvent(KeyDownEvent, this, e);
}
///
/// Event identifier for handlers when attaching the event
///
public const string KeyUpEvent = "Control.KeyUp";
///
/// Occurs when a key was released
///
///
public event EventHandler KeyUp
{
add { Properties.AddHandlerEvent(KeyUpEvent, value); }
remove { Properties.RemoveEvent(KeyUpEvent, value); }
}
///
/// Raises the event.
///
/// Key event arguments
protected virtual void OnKeyUp(KeyEventArgs e)
{
Properties.TriggerEvent(KeyUpEvent, this, e);
}
///
/// Event identifier for handlers when attaching the event
///
public const string TextInputEvent = "Control.TextInput";
///
/// Occurs when text is input for the control. Currently only partially supported on iOS.
///
public event EventHandler TextInput
{
add { Properties.AddHandlerEvent(TextInputEvent, value); }
remove { Properties.RemoveEvent(TextInputEvent, value); }
}
///
/// Raises the event.
///
/// Event arguments
protected virtual void OnTextInput(TextInputEventArgs e)
{
Properties.TriggerEvent(TextInputEvent, this, e);
}
///
/// Event identifier for handlers when attaching the event
///
public const string MouseDownEvent = "Control.MouseDown";
///
/// Occurs when a mouse button has been pressed
///
///
/// Controls will typically capture the mouse after a mouse button is pressed and will be released
/// only after the event.
///
///
public event EventHandler MouseDown
{
add { Properties.AddHandlerEvent(MouseDownEvent, value); }
remove { Properties.RemoveEvent(MouseDownEvent, value); }
}
///
/// Raises the event.
///
///
/// To override default behaviour of the control, set property to true .
///
/// Event arguments
protected virtual void OnMouseDown(MouseEventArgs e)
{
Properties.TriggerEvent(MouseDownEvent, this, e);
}
///
/// Event identifier for handlers when attaching the event
///
public const string MouseUpEvent = "Control.MouseUp";
///
/// Occurs when a mouse button is released
///
///
public event EventHandler MouseUp
{
add { Properties.AddHandlerEvent(MouseUpEvent, value); }
remove { Properties.RemoveEvent(MouseUpEvent, value); }
}
///
/// Raises the event.
///
/// Event arguments
protected virtual void OnMouseUp(MouseEventArgs e)
{
Properties.TriggerEvent(MouseUpEvent, this, e);
}
///
/// Event identifier for handlers when attaching the event
///
public const string MouseMoveEvent = "Control.MouseMove";
///
/// Occurs when mouse moves within the bounds of the control, or when the mouse is captured
///
///
/// The mouse is captured after a event within the control,
/// and is released when the mouse button is released
///
///
///
public event EventHandler MouseMove
{
add { Properties.AddHandlerEvent(MouseMoveEvent, value); }
remove { Properties.RemoveEvent(MouseMoveEvent, value); }
}
///
/// Raises the event.
///
/// Mouse event args
protected virtual void OnMouseMove(MouseEventArgs e)
{
Properties.TriggerEvent(MouseMoveEvent, this, e);
}
///
/// Event identifier for handlers when attaching the event
///
public const string MouseLeaveEvent = "Control.MouseLeave";
///
/// Occurs when mouse leaves the bounds of the control
///
public event EventHandler MouseLeave
{
add { Properties.AddHandlerEvent(MouseLeaveEvent, value); }
remove { Properties.RemoveEvent(MouseLeaveEvent, value); }
}
///
/// Raises the event.
///
/// Mouse event arguments
///
protected virtual void OnMouseLeave(MouseEventArgs e)
{
Properties.TriggerEvent(MouseLeaveEvent, this, e);
}
///
/// Event identifier for handlers when attaching the event
///
public const string MouseEnterEvent = "Control.MouseEnter";
///
/// Occurs when the mouse enters the bounds of the control
///
///
public event EventHandler MouseEnter
{
add { Properties.AddHandlerEvent(MouseEnterEvent, value); }
remove { Properties.RemoveEvent(MouseEnterEvent, value); }
}
///
/// Raises the event.
///
/// Mouse event arguments
protected virtual void OnMouseEnter(MouseEventArgs e)
{
Properties.TriggerEvent(MouseEnterEvent, this, e);
}
///
/// Event identifier for handlers when attaching the event
///
public const string MouseDoubleClickEvent = "Control.MouseDoubleClick";
///
/// Occurs when a mouse button is double clicked within the bounds of the control
///
///
/// If you do not set the property to true, and the default behaviour of
/// the control does not accept double clicks, the event will be called for each click of
/// the mouse button.
///
/// For example, if the user clicks twice in succession, the following will be called:
/// 1. MouseDown for the first click
/// 2. MouseDoubleClick for the second click
/// 3. If Handled has not been set in #2, MouseDown will be called a 2nd time
///
///
public event EventHandler MouseDoubleClick
{
add { Properties.AddHandlerEvent(MouseDoubleClickEvent, value); }
remove { Properties.RemoveEvent(MouseDoubleClickEvent, value); }
}
///
/// Raises the mouse event.
///
/// Mouse event arguments
protected virtual void OnMouseDoubleClick(MouseEventArgs e)
{
Properties.TriggerEvent(MouseDoubleClickEvent, this, e);
}
///
/// Event identifier for handlers when attaching the event
///
public const string MouseWheelEvent = "Control.MouseWheel";
///
/// Occurs when mouse wheel has been changed
///
public event EventHandler MouseWheel
{
add { Properties.AddHandlerEvent(MouseWheelEvent, value); }
remove { Properties.RemoveEvent(MouseWheelEvent, value); }
}
///
/// Raises the event.
///
/// Event arguments
protected virtual void OnMouseWheel(MouseEventArgs e)
{
Properties.TriggerEvent(MouseWheelEvent, this, e);
}
///
/// Event identifier for handlers when attaching the event
///
public const string GotFocusEvent = "Control.GotFocus";
///
/// Occurs when the control receives keyboard focus.
///
///
/// Note that not all controls can recieve keyboard focus.
///
///
public event EventHandler GotFocus
{
add { Properties.AddHandlerEvent(GotFocusEvent, value); }
remove { Properties.RemoveEvent(GotFocusEvent, value); }
}
///
/// Raises the event.
///
/// Event arguments
protected virtual void OnGotFocus(EventArgs e)
{
Properties.TriggerEvent(GotFocusEvent, this, e);
}
///
/// Event identifier for handlers when attaching the event
///
public const string LostFocusEvent = "Control.LostFocus";
///
/// Occurs when control loses keyboard focus
///
///
/// Note that not all controls can recieve keyboard focus
///
///
public event EventHandler LostFocus
{
add { Properties.AddHandlerEvent(LostFocusEvent, value); }
remove { Properties.RemoveEvent(LostFocusEvent, value); }
}
///
/// Raises the event.
///
/// Event arguments
protected virtual void OnLostFocus(EventArgs e)
{
Properties.TriggerEvent(LostFocusEvent, this, e);
}
///
/// Event identifier for handlers when attaching the event
///
public const string ShownEvent = "Control.Shown";
///
/// Occurs when the control is shown on the screen
///
///
/// This event fires when the property changes, or when initially showing a control
/// on a form.
///
public event EventHandler Shown
{
add { Properties.AddHandlerEvent(ShownEvent, value); }
remove { Properties.RemoveEvent(ShownEvent, value); }
}
///
/// Raises the event.
///
/// Event arguments
protected virtual void OnShown(EventArgs e)
{
Properties.TriggerEvent(ShownEvent, this, e);
}
///
/// Event identifier for handlers when attaching the event
///
public const string ThemeChangedEvent = "Control.ThemeChanged";
///
/// Occurs when the control's theme changes either due to a system theme change
/// or when Application.Instance.CurrentTheme is set.
///
public event EventHandler ThemeChanged
{
add { Properties.AddHandlerEvent(ThemeChangedEvent, value); }
remove { Properties.RemoveEvent(ThemeChangedEvent, value); }
}
///
/// Raises the event.
///
/// Event arguments
protected virtual void OnThemeChanged(EventArgs e)
{
Properties.TriggerEvent(ThemeChangedEvent, this, e);
}
static readonly object PreLoadKey = new object();
///
/// Occurs before the control is loaded. See the event for more detail.
///
///
///
///
public event EventHandler PreLoad
{
add { Properties.AddEvent(PreLoadKey, value); }
remove { Properties.RemoveEvent(PreLoadKey, value); }
}
///
/// Raises the event.
///
/// Event arguments
protected virtual void OnPreLoad(EventArgs e)
{
Properties.TriggerEvent(PreLoadKey, this, e);
Handler.OnPreLoad(e);
OnApplyCascadingStyles();
}
static readonly object LoadKey = new object();
///
/// Occurs when the control is displayed on a visible window
///
///
/// A control is loaded when it is part of the control hierarchy and is shown on a window.
/// When the control is removed from the hierarchy, or the window is closed, the event
/// will be called.
///
///
///
///
public event EventHandler Load
{
add { Properties.AddEvent(LoadKey, value); }
remove { Properties.RemoveEvent(LoadKey, value); }
}
///
/// Raises the event.
///
/// Event arguments
protected virtual void OnLoad(EventArgs e)
{
#if DEBUG
if (Loaded)
throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, "Control was loaded more than once"));
#endif
Properties.TriggerEvent(LoadKey, this, e);
Handler.OnLoad(e);
Loaded = true;
}
static readonly object LoadCompleteKey = new object();
///
/// Occurs when the load is complete, which happens after the event and before the window/control is shown.
///
///
/// This is a good place to reposition a Window before it is shown.
///
///
///
///
public event EventHandler LoadComplete
{
add { Properties.AddEvent(LoadCompleteKey, value); }
remove { Properties.RemoveEvent(LoadCompleteKey, value); }
}
///
/// Raises the event.
///
/// Event arguments
protected virtual void OnLoadComplete(EventArgs e)
{
Properties.TriggerEvent(LoadCompleteKey, this, e);
Handler.OnLoadComplete(e);
}
static readonly object UnLoadKey = new object();
///
/// Occurs when the control is unloaded, which happens when removed from the control hierarchy or the window is closed.
///
///
///
///
public event EventHandler UnLoad
{
add { Properties.AddEvent(UnLoadKey, value); }
remove { Properties.RemoveEvent(UnLoadKey, value); }
}
///
/// Raises the event.
///
/// Event arguments
protected virtual void OnUnLoad(EventArgs e)
{
#if DEBUG
if (!Loaded)
throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, "Control was unloaded more than once"));
#endif
Loaded = false;
IsLoadComplete = false;
Properties.TriggerEvent(UnLoadKey, this, e);
Handler.OnUnLoad(e);
}
///
/// Event identifier for handlers when attaching the event
///
public const string DragDropEvent = "Control.DragDrop";
///
/// Occurs when a drag operation is dropped onto the control.
///
///
/// This should perform any of the actual drop logic and update the control state to reflect the dropped data.
/// Any cleanup should be performed in the event, which is called immediately before this event.
///
public event EventHandler DragDrop
{
add { Properties.AddHandlerEvent(DragDropEvent, value); }
remove { Properties.RemoveEvent(DragDropEvent, value); }
}
///
/// Raises the event.
///
/// Event arguments
protected virtual void OnDragDrop(DragEventArgs e)
{
Properties.TriggerEvent(DragDropEvent, this, e);
}
///
/// Event identifier for handlers when attaching the event
///
public const string DragOverEvent = "Control.DragOver";
///
/// Occurs when a drag operation is over the control and needs updating based on position or keyboard state changes.
///
public event EventHandler DragOver
{
add { Properties.AddHandlerEvent(DragOverEvent, value); }
remove { Properties.RemoveEvent(DragOverEvent, value); }
}
///
/// Raises the event.
///
/// Event arguments
protected virtual void OnDragOver(DragEventArgs e) => Properties.TriggerEvent(DragOverEvent, this, e);
///
/// Event identifier for handlers when attaching the event
///
public const string DragEnterEvent = "Control.DragEnter";
///
/// Occurs when a drag operation enters the bounds of the control.
///
public event EventHandler DragEnter
{
add { Properties.AddHandlerEvent(DragEnterEvent, value); }
remove { Properties.RemoveEvent(DragEnterEvent, value); }
}
///
/// Raises the event.
///
/// Event arguments
protected virtual void OnDragEnter(DragEventArgs e) => Properties.TriggerEvent(DragEnterEvent, this, e);
///
/// Event identifier for handlers when attaching the event
///
public const string DragLeaveEvent = "Control.DragLeave";
///
/// Occurs when a drag operation leaves the bounds of the control or the drag operation was completed inside the control.
///
///
/// Use this event to 'clean up' any state of the control for the current drag operation.
/// This will be called before the event.
///
public event EventHandler DragLeave
{
add { Properties.AddHandlerEvent(DragLeaveEvent, value); }
remove { Properties.RemoveEvent(DragLeaveEvent, value); }
}
///
/// Raises the event.
///
/// Event arguments
protected virtual void OnDragLeave(DragEventArgs e) => Properties.TriggerEvent(DragLeaveEvent, this, e);
///
/// Event identifier for handlers when attaching the event
///
public const string DragEndEvent = "Control.DragEnd";
///
/// Occurs for a source control after a call to when the drag operation has ended.
/// The is the final used at the drop destination.
///
///
/// For controls that you are dragging from this event is useful to know what to do with the dragged content after it is dropped in a different control or application.
///
public event EventHandler DragEnd
{
add { Properties.AddHandlerEvent(DragEndEvent, value); }
remove { Properties.RemoveEvent(DragEndEvent, value); }
}
///
/// Raises the event.
///
/// Event arguments
protected virtual void OnDragEnd(DragEventArgs e) => Properties.TriggerEvent(DragEndEvent, this, e);
///
/// Event identifier for handlers when attaching the event
///
public const string EnabledChangedEvent = "Control.EnabledChanged";
///
/// Occurs when the value is changed.
///
public event EventHandler EnabledChanged
{
add { Properties.AddHandlerEvent(EnabledChangedEvent, value); }
remove { Properties.RemoveEvent(EnabledChangedEvent, value); }
}
///
/// Raises the event.
///
/// Event arguments
protected virtual void OnEnabledChanged(EventArgs e) => Properties.TriggerEvent(EnabledChangedEvent, this, e);
#endregion
static Control()
{
EventLookup.Register(c => c.OnGotFocus(null), Control.GotFocusEvent);
EventLookup.Register(c => c.OnKeyDown(null), Control.KeyDownEvent);
EventLookup.Register(c => c.OnKeyUp(null), Control.KeyUpEvent);
EventLookup.Register(c => c.OnLostFocus(null), Control.LostFocusEvent);
EventLookup.Register(c => c.OnMouseDoubleClick(null), Control.MouseDoubleClickEvent);
EventLookup.Register(c => c.OnMouseDown(null), Control.MouseDownEvent);
EventLookup.Register(c => c.OnMouseEnter(null), Control.MouseEnterEvent);
EventLookup.Register(c => c.OnMouseLeave(null), Control.MouseLeaveEvent);
EventLookup.Register(c => c.OnMouseMove(null), Control.MouseMoveEvent);
EventLookup.Register(c => c.OnMouseUp(null), Control.MouseUpEvent);
EventLookup.Register(c => c.OnMouseWheel(null), Control.MouseWheelEvent);
EventLookup.Register(c => c.OnShown(null), Control.ShownEvent);
EventLookup.Register(c => c.OnSizeChanged(null), Control.SizeChangedEvent);
EventLookup.Register(c => c.OnTextInput(null), Control.TextInputEvent);
EventLookup.Register(c => c.OnDragDrop(null), Control.DragDropEvent);
EventLookup.Register(c => c.OnDragOver(null), Control.DragOverEvent);
EventLookup.Register(c => c.OnDragEnter(null), Control.DragEnterEvent);
EventLookup.Register(c => c.OnDragLeave(null), Control.DragLeaveEvent);
EventLookup.Register(c => c.OnDragEnd(null), Control.DragEndEvent);
EventLookup.Register(c => c.OnEnabledChanged(null), Control.EnabledChangedEvent);
EventLookup.Register(c => c.OnThemeChanged(null), Control.ThemeChangedEvent);
}
///
/// Initializes a new instance of the class.
///
protected Control()
{
}
///
/// Initializes a new instance of the Container with the specified handler
///
/// Pre-created handler to attach to this instance
public Control(IHandler handler)
: base(handler)
{
}
///
/// Queues a repaint of the entire control on the screen and any of its children.
///
///
/// This is only useful when the control is visible.
///
public void Invalidate()
{
Handler.Invalidate(true);
}
///
/// Queues a repaint of the entire control on the screen
///
///
/// This is only useful when the control is visible.
///
/// True to invalidate all children, false to only invalidate the container
public void Invalidate(bool invalidateChildren)
{
Handler.Invalidate(invalidateChildren);
}
///
/// Queues a repaint of the specified of the control and any children.
///
///
/// This is only useful when the control is visible.
///
/// Rectangle to repaint
public void Invalidate(Rectangle rect)
{
Handler.Invalidate(rect, true);
}
///
/// Queues a repaint of the specified of the control
///
///
/// This is only useful when the control is visible.
///
/// Rectangle to repaint
/// True to invalidate all children, false to only invalidate the container
public void Invalidate(Rectangle rect, bool invalidateChildren)
{
Handler.Invalidate(rect, invalidateChildren);
}
///
/// Updates the layout of this control if necessary.
///
///
/// This will ensure the control has had all of its layout applied so you can use its position and size right after this call.
/// Most platforms (except WinForms) use a deferred layout system so that after adding your control to the form dynamically it won't
/// get laid out until the next idle loop.
/// This is useful when you need to know the dimensions of the control immediately.
/// Note that this can be an expensive operation, so it is recommended to only call this method when necessary and after all of the
/// controls have been added/updated.
///
public void UpdateLayout() => Handler.UpdateLayout();
///
/// Gets or sets the size of the control. Use -1 to specify auto sizing for either the width and/or height.
///
///
/// Setting the size of controls is entirely optional as most controls will size themselves appropriately.
/// When specifying a size, it will be used as the desired size of the control. The container will reposition
/// and resize the control depending on the available size.
///
/// For a , it is preferred to set the instead, as various
/// platforms have different sizes of window decorations, toolbars, etc.
///
/// The current size of the control
public virtual Size Size
{
get { return Handler.Size; }
set { Handler.Size = value; }
}
///
/// Gets the preferred size of this control given infinite space available.
///
/// The size this control would prefer to be
public SizeF GetPreferredSize() => GetPreferredSize(SizeF.PositiveInfinity);
///
/// Gets the preferred size of this control given the specified .
///
/// The available size to determine the preferred size
/// The preferred size this control would like to be, which can be larger than the specified .
public SizeF GetPreferredSize(SizeF availableSize)
{
// hack for now for dynamic layouts.. this should be moved to the Measure infrastructure when implemented..
InternalEnsureLayout();
return Handler.GetPreferredSize(availableSize);
}
internal virtual void InternalEnsureLayout()
{
}
///
/// Gets a value indicating this control currently has mouse capture
///
///
/// Mouse capture can happen during a handled MouseDown event until MouseUp,
/// or it can be captured explicitly via .
///
public bool IsMouseCaptured => Handler.IsMouseCaptured;
///
/// Captures all mouse events to this control.
///
///
/// This captures all mouse events until is called.
///
/// Note that not all platforms will allow a mouse capture unless the mouse is currently down.
///
/// true if the mouse was captured, false otherwise.
public bool CaptureMouse() => Handler.CaptureMouse();
///
/// Releases the mouse capture after a call to .
///
public void ReleaseMouseCapture() => Handler.ReleaseMouseCapture();
///
/// Gets or sets the width of the control size.
///
public virtual int Width
{
get => Handler.Width;
set => Handler.Width = value;
}
///
/// Gets or sets the height of the control size.
///
public virtual int Height
{
get => Handler.Height;
set => Handler.Height = value;
}
///
/// Gets or sets a value indicating whether this (or its children) are enabled and accept user input.
///
///
/// Typically when a control is disabled, the user cannot do anything with the control or any of its children.
/// Including for example, selecting text in a text control.
/// Certain controls can have a 'Read Only' mode, such as which allow the user to
/// select text, but not change its contents.
///
/// true if enabled; otherwise, false .
[sc.DefaultValue(true)]
public virtual bool Enabled
{
get => Handler.Enabled;
set => Handler.Enabled = value;
}
///
/// Gets or sets a value indicating whether this is visible to the user.
///
///
/// When the visibility of a control is set to false, it will not occupy space in the layout.
///
/// true if visible; otherwise, false .
[sc.DefaultValue(true)]
public virtual bool Visible
{
get { return Handler.Visible; }
set { Handler.Visible = value; }
}
///
/// Gets the container which this control has been added to, if any
///
/// The parent control, or null if there is no parent
public new Container Parent
{
get { return base.Parent as Container; }
}
///
/// Gets or sets the logical parent, which excludes any visual structure of custom containers.
///
/// The logical parent.
internal Container InternalLogicalParent
{
get { return base.Parent as Container; }
set { base.Parent = value; }
}
static readonly object VisualParent_Key = new object();
///
/// Gets the visual container of this control, if any.
///
///
/// Some containers may use other Eto controls to layout its children, such as the .
/// This will return the parent control that visually contains this control as opposed to
/// which will return the logical parent.
///
/// The visual parent of this control.
public Container VisualParent
{
get { return Properties.Get(VisualParent_Key); }
internal set
{
var old = VisualParent;
if (Properties.TrySet(VisualParent_Key, value))
{
Handler.SetParent(old, value);
}
}
}
///
/// Finds a control in the parent hierarchy with the specified type and if specified
///
/// The parent if found, or null if not found.
/// The type of control to find.
/// Identifier of the parent control to find, or null to find by type only.
public new Container FindParent(Type type, string id = null)
{
var control = Parent;
while (control != null)
{
if ((type == null || type.IsInstanceOfType(control)) && (string.IsNullOrEmpty(id) || control.ID == id))
{
return control;
}
control = control.Parent;
}
return null;
}
///
/// Finds a control in the parent hierarchy with the specified
///
/// The parent if found, or null if not found.
/// Identifier of the parent control to find.
public new Container FindParent(string id) => FindParent(null, id);
///
/// Detaches the control by removing it from its parent
///
///
/// This is essentially a shortcut to myControl.Parent.Remove(myControl);
///
public void Detach()
{
VisualParent?.Remove(this);
Parent?.Remove(this);
}
static readonly object IsAttached_Key = new object();
///
/// Gets a value indicating this control has been attached to a native container
///
///
public bool IsAttached
{
get => Properties.Get(IsAttached_Key);
private set => Properties.Set(IsAttached_Key, value);
}
///
/// Attaches the control for direct use in a native application
///
///
/// Use this to use a control directly in a native application. Note that the native application must be running
/// the same framework as the current platform. E.g. a WinForms application can use an Eto.Forms control
/// when using the Eto.WinForms platform.
///
/// This prepares the control by firing the , , etc. events.
///
public void AttachNative()
{
if (VisualParent != null)
throw new InvalidOperationException("You can only attach a parentless control");
if (IsAttached)
return;
IsAttached = true;
using (Platform.Context)
{
OnPreLoad(EventArgs.Empty);
OnLoad(EventArgs.Empty);
Application.Instance.AsyncInvoke(PostAttach);
}
}
void PostAttach()
{
// if the control is disposed before we get here Handler will be null, so omit calling OnLoadComplete
if (!IsDisposed && Handler != null && Loaded)
RaiseLoadComplete(EventArgs.Empty);
}
///
/// Raises LoadComplete unless it has already been raised since the control was loaded.
///
/// Event arguments
/// Raise it even if it has already been raised, e.g. when a loaded window is shown again.
internal void RaiseLoadComplete(EventArgs e, bool always = false)
{
if (IsLoadComplete && !always)
return;
IsLoadComplete = true;
OnLoadComplete(e);
}
///
/// Detaches the control when it is used in a native application, when you want to reuse the control.
///
///
/// This should only be called after has been called, which is usually done by calling
/// to ToNative(true) .
///
public void DetachNative()
{
if (!IsAttached)
return;
IsAttached = false;
using (Platform.Context)
{
OnUnLoad(EventArgs.Empty);
}
}
internal void TriggerPreLoad(EventArgs e)
{
using (Platform.Context)
OnPreLoad(e);
}
internal void TriggerLoad(EventArgs e)
{
using (Platform.Context)
OnLoad(e);
}
internal void TriggerLoadComplete(EventArgs e)
{
using (Platform.Context)
RaiseLoadComplete(e);
}
internal void TriggerUnLoad(EventArgs e)
{
using (Platform.Context)
OnUnLoad(e);
}
internal void TriggerStyleChanged(EventArgs e)
{
using (Platform.Context)
OnStyleChanged(e);
}
///
/// Gets or sets the color for the background of the control
///
///
/// Note that on some platforms (e.g. Mac), setting the background color of a control can change the performance
/// characteristics of the control and its children, since it must enable layers to do so.
///
/// The color of the background.
public virtual Color BackgroundColor
{
get { return Handler.BackgroundColor; }
set { Handler.BackgroundColor = value; }
}
///
/// Gets a value indicating whether this instance has the keyboard input focus.
///
/// true if this instance has focus; otherwise, false .
public virtual bool HasFocus => Handler.HasFocus;
///
/// Attempts to set the keyboard input focus to this control, or the first child that accepts focus.
/// For Windows, this will bring it to front and activate it.
///
public virtual void Focus() => Handler.Focus();
static readonly object SuspendCount_Key = new object();
int SuspendCount
{
get { return Properties.Get(SuspendCount_Key); }
set { Properties.Set(SuspendCount_Key, value); }
}
///
/// Gets a value indicating whether the layout of child controls is suspended.
///
///
///
/// true if this instance is suspended; otherwise, false .
public bool IsSuspended => SuspendCount > 0;
///
/// Suspends the layout of child controls
///
///
/// This can be used to optimize some platforms while adding, removing, or changing many child controls at once.
/// It disables the calculation of control positioning until is called.
/// Each call to SuspendLayout() must be balanced with a call to .
///
public virtual void SuspendLayout()
{
SuspendCount++;
Handler.SuspendLayout();
}
///
/// Resumes the layout after it has been suspended, and performs a layout
///
///
/// This can be used to optimize some platforms while adding, removing, or changing many child controls at once.
/// Each call to ResumeLayout() must be balanced with a call to before it.
///
public virtual void ResumeLayout()
{
var count = SuspendCount;
if (count == 0)
throw new InvalidOperationException("Control is not suspended. You must balance calls to Resume() with Suspend()");
SuspendCount = --count;
Handler.ResumeLayout();
}
///
/// Gets the window this control is contained in
///
/// The parent window, or null if it is not currently on a window
public Window ParentWindow
{
get
{
Control c = this;
while (c != null)
{
var window = c as Window;
if (window != null)
return window;
c = c.VisualParent;
}
return Handler.GetNativeParentWindow();
}
}
///
/// Gets the supported platform commands that can be used to hook up system functions to user defined logic
///
///
/// This lists all available commands that can be mapped using the method
/// of the control.
///
/// The supported platform commands.
///
public IEnumerable SupportedPlatformCommands => Handler.SupportedPlatformCommands;
///
/// Specifies a command to execute for a platform-specific command
///
///
/// Some platforms have specific system-defined commands that can be associated with a control.
/// For example, the Mac platform's cut/copy/paste functionality is defined by the system, and if you want to
/// hook into it, you can use this to map it to your own defined logic.
/// The valid values of the parameter are defined by each platform, and a list can be
/// retrieved using
///
///
/// This example shows how to extend a control with cut/copy/paste for the mac platform:
///
/// var drawable = new Drawable();
/// if (drawable.Generator.IsMac)
/// {
/// drawable.MapPlatformCommand("cut", new MyCutCommand());
/// drawable.MapPlatformCommand("copy", new MyCopyCommand());
/// drawable.MapPlatformCommand("paste", new MyPasteCommand());
/// }
///
///
/// System command
/// Command to execute, or null to restore to the default behavior
///
public void MapPlatformCommand(string systemCommand, Command command) => Handler.MapPlatformCommand(systemCommand, command);
///
/// Converts a point from screen space to control space.
///
/// The point in control space
/// Point in screen space
public PointF PointFromScreen(PointF point) => Handler.PointFromScreen(point);
///
/// Converts a point from control space to screen space
///
/// The point in screen space
/// Point in control space
public PointF PointToScreen(PointF point) => Handler.PointToScreen(point);
///
/// Converts a rectangle from control space to screen space
///
/// The rectangle in screen space
/// Rectangle in control space
public RectangleF RectangleToScreen(RectangleF rect) => new RectangleF(PointToScreen(rect.Location), PointToScreen(rect.EndLocation));
///
/// Converts a rectangle from screen space to control space.
///
/// The rectangle in control space
/// Rectangle in screen space
public RectangleF RectangleFromScreen(RectangleF rect) => new RectangleF(PointFromScreen(rect.Location), PointFromScreen(rect.EndLocation));
///
/// Gets the bounding rectangle of this control relative to its container
///
/// The bounding rectangle of the control
public Rectangle Bounds => new Rectangle(Location, Size);
///
/// Gets the location of the control as positioned by the container
///
///
/// A control's location is set by the container.
/// This can be used to determine where the control is for overlaying floating windows, menus, etc.
///
/// The current location of the control
public Point Location => Handler.Location;
///
/// Gets or sets the type of cursor to use when the mouse is hovering over the control
///
/// The mouse cursor
public virtual Cursor Cursor
{
get { return Handler.Cursor; }
set { Handler.Cursor = value; }
}
///
/// Gets or sets the tool tip to show when the mouse is hovered over the control
///
/// The tool tip.
public virtual string ToolTip
{
get { return Handler.ToolTip; }
set { Handler.ToolTip = value; }
}
///
/// Gets or sets the tab index order for this control within its container.
///
///
/// This sets the order when using the tab key to cycle through controls
///
/// Note that some platforms (Gtk and WinForms) may not support setting the context of the tab order to StackLayout
/// or DynamicLayout containers and may not behave exactly as expected. Use the
/// flag to determine if it is supported.
///
/// The index of the control in the tab order.
[sc.DefaultValue(int.MaxValue)]
public virtual int TabIndex
{
get { return Handler.TabIndex; }
set { Handler.TabIndex = value; }
}
///
/// Gets or sets a value indicating whether the user can get to this control using the tab key.
///
///
/// When false , the control is skipped when cycling through controls with the tab key, but can still be
/// focused by clicking on it or by calling .
/// This is useful for composite controls where only part of the control should be in the tab order, such as
/// the spinner of a or .
///
/// The tab key only cycles through the controls within a window, so this has no effect for a .
///
/// Note that on Gtk this maps directly to whether the underlying widget can be focused, so it also prevents the
/// control from being focused by clicking on it, and controls that never accept focus (such as a )
/// will report false . On iOS and Android this has no effect.
///
/// true to include the control in the tab order (the default); false to skip it.
[sc.DefaultValue(true)]
public virtual bool TabStop
{
get { return Handler.TabStop; }
set { Handler.TabStop = value; }
}
///
/// Gets or sets a value indicating whether this control can serve as drop target.
///
public virtual bool AllowDrop
{
get { return Handler.AllowDrop; }
set { Handler.AllowDrop = value; }
}
///
/// Starts drag operation using this control as drag source.
///
///
/// This method can be blocking on some platforms (Wpf, WinForms), and non-blocking on others (Mac, Gtk).
/// Use the event to determine when the drag operation is completed and get its resulting DragEffects.
///
/// Drag data.
/// Allowed action.
public virtual void DoDragDrop(DataObject data, DragEffects allowedEffects)
{
Handler.DoDragDrop(data, allowedEffects, null, PointF.Empty);
}
///
/// Starts drag operation using this control as drag source.
///
///
/// This method can be blocking on some platforms (Wpf, WinForms), and non-blocking on others (Mac, Gtk).
/// Use the event to determine when the drag operation is completed and get its resulting DragEffects.
///
/// Drag data.
/// Allowed effects.
/// Custom drag image
/// Offset of the cursor to the drag image
public virtual void DoDragDrop(DataObject data, DragEffects allowedEffects, Image image, PointF cursorOffset)
{
Handler.DoDragDrop(data, allowedEffects, image, cursorOffset);
}
///
/// Handles when the is changed.
///
///
/// This applies the cascading styles to the control and any of its children.
///
protected override void OnStyleChanged(EventArgs e)
{
base.OnStyleChanged(e);
// already loaded, re-apply styles as they have changed
if (Loaded)
OnApplyCascadingStyles();
}
///
/// Triggers the StyleChanged event and re-applies the styles to this control and its children.
///
public void TriggerStyleChanged() => OnStyleChanged(EventArgs.Empty);
///
/// Called when cascading styles should be applied to this control.
///
///
/// You don't typically have to call this directly, but override it to apply styles to any child item(s)
/// that may need styling at the same time.
///
/// This is automatically done for any Container based control and its child controls.
///
protected virtual void OnApplyCascadingStyles() => ApplyStyles(this, Style);
///
/// Applies the styles to the specified up the parent chain.
///
///
/// This traverses up the parent chain to apply any cascading styles defined in parent container objects.
///
/// Call this method on any child widget of a control.
///
/// Widget to style.
/// Style of the widget to apply.
protected virtual void ApplyStyles(object widget, string style) => Parent?.ApplyStyles(widget, Style);
///
/// Shows a print dialog to print the specified control
///
public void Print()
{
using (var doc = new PrintDocument(this))
{
var dlg = new PrintDialog();
dlg.ShowDialog(this, doc);
}
}
///
/// Gets or sets the context menu that appears when the user right-clicks on the control.
///
///
/// On some platforms and controls, such as macOS, the context menu can have additional items added by the system.
///
/// Also the menu may appear when pressing different keys, such as a control-click on macOS, or when
/// pressing the menu key on Windows keyboards.
///
/// There is also some other semantic differences of using this vs. showing a context menu manually, such as on Windows,
/// right clicking on a TextBox or TextArea will keep the selection visible, whereas this would not be the case if you showed
/// the context menu manually.
///
public ContextMenu ContextMenu
{
get { return Handler.ContextMenu; }
set { Handler.ContextMenu = value; }
}
///
/// Handles the disposal of this control
///
/// True if the caller called manually, false if being called from a finalizer
protected override void Dispose(bool disposing)
{
if (disposing)
{
Unbind();
Detach();
DetachNative();
}
base.Dispose(disposing);
}
///
/// Converts a string to a label control implicitly.
///
///
/// This provides an easy way to add labels to your layout through code, without having to create instances.
///
/// Text to convert to a Label control.
public static implicit operator Control(string labelText)
{
return new Label { Text = labelText };
}
///
/// Converts an to a control implicitly.
///
///
/// This provides an easy way to add images to your layout through code, without having to create instances manually.
///
/// Image to convert to an ImageView control.
public static implicit operator Control(Image image)
{
return new ImageView { Image = image };
}
#region Callback
static readonly object callback = new Callback();
///
/// Gets an instance of an object used to perform callbacks to the widget from handler implementations.
///
/// The callback instance to use for this widget
protected override object GetCallback() { return callback; }
///
/// Callback interface for instances of
///
public new interface ICallback : Widget.ICallback
{
///
/// Raises the key down event.
///
void OnKeyDown(Control widget, KeyEventArgs e);
///
/// Raises the key up event.
///
void OnKeyUp(Control widget, KeyEventArgs e);
///
/// Raises the mouse down event.
///
void OnMouseDown(Control widget, MouseEventArgs e);
///
/// Raises the mouse up event.
///
void OnMouseUp(Control widget, MouseEventArgs e);
///
/// Raises the mouse move event.
///
void OnMouseMove(Control widget, MouseEventArgs e);
///
/// Raises the mouse leave event.
///
void OnMouseLeave(Control widget, MouseEventArgs e);
///
/// Raises the mouse enter event.
///
void OnMouseEnter(Control widget, MouseEventArgs e);
///
/// Raises the text input event.
///
void OnTextInput(Control widget, TextInputEventArgs e);
///
/// Raises the size changed event.
///
void OnSizeChanged(Control widget, EventArgs e);
///
/// Raises the mouse double click event.
///
void OnMouseDoubleClick(Control widget, MouseEventArgs e);
///
/// Raises the mouse wheel event.
///
void OnMouseWheel(Control widget, MouseEventArgs e);
///
/// Raises the got focus event.
///
void OnGotFocus(Control widget, EventArgs e);
///
/// Raises the lost focus event.
///
void OnLostFocus(Control widget, EventArgs e);
///
/// Raises the shown event.
///
void OnShown(Control widget, EventArgs e);
///
/// Raises the DragDrop event.
///
void OnDragDrop(Control widget, DragEventArgs e);
///
/// Raises the DragOver event.
///
void OnDragOver(Control widget, DragEventArgs e);
///
/// Raises the DragEnter event.
///
void OnDragEnter(Control widget, DragEventArgs e);
///
/// Raises the DragLeave event.
///
void OnDragLeave(Control widget, DragEventArgs e);
///
/// Raises the DragEnd event.
///
void OnDragEnd(Control widget, DragEventArgs e);
///
/// Raises the EnabledChanged event.
///
void OnEnabledChanged(Control widget, EventArgs e);
///
/// Raises the ThemeChanged event.
///
void OnThemeChanged(Control widget, EventArgs e);
}
///
/// Callback methods for handlers of
///
protected class Callback : ICallback
{
///
/// Raises the key down event.
///
public void OnKeyDown(Control widget, KeyEventArgs e)
{
using (widget.Platform.Context)
widget.OnKeyDown(e);
}
///
/// Raises the key up event.
///
public void OnKeyUp(Control widget, KeyEventArgs e)
{
using (widget.Platform.Context)
widget.OnKeyUp(e);
}
///
/// Raises the mouse down event.
///
public void OnMouseDown(Control widget, MouseEventArgs e)
{
using (widget.Platform.Context)
widget.OnMouseDown(e);
}
///
/// Raises the mouse up event.
///
public void OnMouseUp(Control widget, MouseEventArgs e)
{
using (widget.Platform.Context)
widget.OnMouseUp(e);
}
///
/// Raises the mouse move event.
///
public void OnMouseMove(Control widget, MouseEventArgs e)
{
using (widget.Platform.Context)
widget.OnMouseMove(e);
}
///
/// Raises the mouse leave event.
///
public void OnMouseLeave(Control widget, MouseEventArgs e)
{
using (widget.Platform.Context)
widget.OnMouseLeave(e);
}
///
/// Raises the mouse enter event.
///
public void OnMouseEnter(Control widget, MouseEventArgs e)
{
using (widget.Platform.Context)
widget.OnMouseEnter(e);
}
///
/// Raises the text input event.
///
public void OnTextInput(Control widget, TextInputEventArgs e)
{
using (widget.Platform.Context)
widget.OnTextInput(e);
}
///
/// Raises the size changed event.
///
public void OnSizeChanged(Control widget, EventArgs e)
{
using (widget.Platform.Context)
widget.OnSizeChanged(e);
}
///
/// Raises the mouse double click event.
///
public void OnMouseDoubleClick(Control widget, MouseEventArgs e)
{
using (widget.Platform.Context)
widget.OnMouseDoubleClick(e);
}
///
/// Raises the mouse wheel event.
///
public void OnMouseWheel(Control widget, MouseEventArgs e)
{
using (widget.Platform.Context)
widget.OnMouseWheel(e);
}
///
/// Raises the got focus event.
///
public void OnGotFocus(Control widget, EventArgs e)
{
using (widget.Platform.Context)
widget.OnGotFocus(e);
}
///
/// Raises the lost focus event.
///
public void OnLostFocus(Control widget, EventArgs e)
{
using (widget.Platform.Context)
widget.OnLostFocus(e);
}
///
/// Raises the shown event.
///
public void OnShown(Control widget, EventArgs e)
{
using (widget.Platform.Context)
widget.OnShown(e);
}
///
/// Raises the DragDrop event.
///
public void OnDragDrop(Control widget, DragEventArgs e)
{
using (widget.Platform.Context)
widget.OnDragDrop(e);
}
///
/// Raises the DragOver event.
///
public void OnDragOver(Control widget, DragEventArgs e)
{
using (widget.Platform.Context)
widget.OnDragOver(e);
}
///
/// Raises the DragEnter event.
///
public void OnDragEnter(Control widget, DragEventArgs e)
{
using (widget.Platform.Context)
widget.OnDragEnter(e);
}
///
/// Raises the DragLeave event.
///
public void OnDragLeave(Control widget, DragEventArgs e)
{
using (widget.Platform.Context)
widget.OnDragLeave(e);
}
///
/// Raises the DragEnd event.
///
public void OnDragEnd(Control widget, DragEventArgs e)
{
using (widget.Platform.Context)
widget.OnDragEnd(e);
}
///
/// Raises the EnabledChanged event.
///
public void OnEnabledChanged(Control widget, EventArgs e)
{
using (widget.Platform.Context)
widget.OnEnabledChanged(e);
}
///
/// Raises the ThemeChanged event.
///
public void OnThemeChanged(Control widget, EventArgs e)
{
using (widget.Platform.Context)
widget.OnThemeChanged(e);
}
}
#endregion
#region Handler
///
/// Handler interface for
///
/// (c) 2014 by Curtis Wensley
/// See LICENSE for full terms
public new interface IHandler : Widget.IHandler, IContextMenuHost
{
///
/// Gets or sets the color for the background of the control
///
///
/// Note that on some platforms (e.g. Mac), setting the background color of a control can change the performance
/// characteristics of the control and its children, since it must enable layers to do so.
///
/// The color of the background.
Color BackgroundColor { get; set; }
///
/// Gets or sets the size of the control. Use -1 to specify auto sizing for either the width and/or height.
///
///
/// Setting the size of controls is entirely optional as most controls will size themselves appropriately.
/// When specifying a size, it will be used as the desired size of the control. The container will reposition
/// and resize the control depending on the available size.
///
/// For a , it is preferred to set the instead, as various
/// platforms have different sizes of window decorations, toolbars, etc.
///
/// The current size of the control
Size Size { get; set; }
///
/// Gets or sets the width of the control size.
///
int Width { get; set; }
///
/// Gets or sets the height of the control size.
///
int Height { get; set; }
///
/// Gets or sets a value indicating whether this is enabled and accepts user input.
///
///
/// Typically when a control is disabled, the user cannot do anything with the control (including for example, selecting
/// text in a text control). Certain controls can have a 'Read Only' mode, such as which
/// allows the user to select text, but not change its contents.
///
/// true if enabled; otherwise, false .
bool Enabled { get; set; }
///
/// Queues a repaint of the entire control on the screen
///
///
/// This is only useful when the control is visible.
///
/// True to invalidate all children, false to only invalidate the container
void Invalidate(bool invalidateChildren);
///
/// Queues a repaint of the specified of the control
///
///
/// This is only useful when the control is visible.
///
/// Rectangle to repaint
/// True to invalidate all children, false to only invalidate the container
void Invalidate(Rectangle rect, bool invalidateChildren);
///
/// Suspends the layout of child controls
///
///
/// This can be used to optimize some platforms while adding, removing, or changing many child controls at once.
/// It disables the calculation of control positioning until is called.
/// Each call to SuspendLayout() must be balanced with a call to .
///
void SuspendLayout();
///
/// Resumes the layout after it has been suspended, and performs a layout
///
///
/// This can be used to optimize some platforms while adding, removing, or changing many child controls at once.
/// Each call to ResumeLayout() must be balanced with a call to before it.
///
void ResumeLayout();
///
/// Attempts to set the keyboard input focus to this control, or the first child that accepts focus
///
void Focus();
///
/// Gets a value indicating whether this instance has the keyboard input focus.
///
/// true if this instance has focus; otherwise, false .
bool HasFocus { get; }
///
/// Gets or sets a value indicating whether this is visible to the user.
///
///
/// When the visibility of a control is set to false, it will still occupy space in the layout, but not be shown.
/// The only exception is for controls like the , which will hide a pane if the visibility
/// of one of the panels is changed.
///
/// true if visible; otherwise, false .
bool Visible { get; set; }
///
/// Called before the control is loaded on a form
///
/// Event arguments
///
///
///
void OnPreLoad(EventArgs e);
///
/// Called when the control is loaded on a form
///
/// Event arguments
///
///
///
void OnLoad(EventArgs e);
///
/// Called after all other controls have been loaded
///
/// Event arguments
///
///
///
void OnLoadComplete(EventArgs e);
///
/// Called when the control is unloaded, which is when it is not currently on a displayed window
///
/// Event arguments
///
///
///
void OnUnLoad(EventArgs e);
///
/// Called when the parent of the control has been set
///
/// Old parent for the control, or null if the control is added
/// New parent for the control, or null if the parent was removed
void SetParent(Container oldParent, Container newParent);
///
/// Gets the supported platform commands that can be used to hook up system functions to user defined logic
///
///
/// This lists all available commands that can be mapped using the method
/// of the control.
///
/// The supported platform commands.
///
IEnumerable SupportedPlatformCommands { get; }
///
/// Specifies a command to execute for a platform-specific command
///
///
/// Some platforms have specific system-defined commands that can be associated with a control.
/// For example, the Mac platform's cut/copy/paste functionality is defined by the system, and if you want to
/// hook into it, you can use this to map it to your own defined logic.
/// The valid values of the parameter are defined by each platform, and a list can be
/// retrieved using
///
///
/// This example shows how to extend a control with cut/copy/paste for the mac platform:
///
/// var drawable = new Drawable();
/// if (drawable.Generator.IsMac)
/// {
/// drawable.MapPlatformCommand("cut", new MyCutCommand());
/// drawable.MapPlatformCommand("copy", new MyCopyCommand());
/// drawable.MapPlatformCommand("paste", new MyPasteCommand());
/// }
///
///
/// System command.
/// Command to execute, or null to restore to the default behavior
///
void MapPlatformCommand(string systemCommand, Command command);
///
/// Converts a point from screen space to control space.
///
/// The point in control space
/// Point in screen space
PointF PointFromScreen(PointF point);
///
/// Converts a point from control space to screen space
///
/// The point in screen space
/// Point in control space
PointF PointToScreen(PointF point);
///
/// Gets the location of the control as positioned by the container
///
///
/// A control's location is set by the container.
/// This can be used to determine where the control is for overlaying floating windows, menus, etc.
///
/// The current location of the control
Point Location { get; }
///
/// Gets or sets the tool tip to show when the mouse is hovered over the control
///
/// The tool tip.
string ToolTip { get; set; }
///
/// Gets or sets the type of cursor to use when the mouse is hovering over the control
///
/// The mouse cursor
Cursor Cursor { get; set; }
///
/// Gets or sets the tab index order for this control within its container.
///
///
/// This sets the order when using the tab key to cycle through controls
///
/// Note that some platforms (Gtk and WinForms) may not support setting the context of the tab order to StackLayout
/// or DynamicLayout containers and may not behave exactly as expected. Use the
/// flag to determine if it is supported.
///
/// The index of the control in the tab order.
int TabIndex { get; set; }
///
/// Gets or sets a value indicating whether the user can get to this control using the tab key.
///
///
/// When false , the control is skipped when cycling through controls with the tab key, but can still be
/// focused by clicking on it or by calling .
///
/// Note that on Gtk this also prevents the control from being focused by clicking on it, and on iOS and Android
/// this has no effect.
///
/// true to include the control in the tab order (the default); false to skip it.
bool TabStop { get; set; }
///
/// Gets an enumeration of controls that are in the visual tree.
///
///
/// This is used to specify which controls are contained by this instance that are part of the visual tree.
/// This should include all controls including non-logical Eto controls used for layout.
///
/// The visual controls.
IEnumerable VisualControls { get; }
///
/// Gets or sets a value indicating whether this control can serve as drop target.
///
bool AllowDrop { get; set; }
///
/// Starts drag operation using this control as drag source.
///
/// Drag data.
/// Allowed effects.
/// Custom drag image
/// Offset of the cursor to the drag image
void DoDragDrop(DataObject data, DragEffects allowedEffects, Image image, PointF cursorOffset);
///
/// Gets a parent window wrapper around the native window
///
/// The parent window.
Window GetNativeParentWindow();
///
/// Gets the preferred size of this control given the specified .
///
/// The available size to determine the preferred size
/// The preferred size this control would like to be, which can be larger than the specified .
SizeF GetPreferredSize(SizeF availableSize);
///
/// Updates the layout of this control if necessary.
///
///
/// This will ensure the control has had all of its layout applied so you can use its position and size right after this call.
/// Most platforms (except WinForms) use a deferred layout system so that after adding your control to the form dynamically it won't
/// get laid out until the next idle loop.
/// This is useful when you need to know the dimensions of the control immediately.
///
void UpdateLayout();
///
/// Gets a value indicating this control currently has mouse capture
///
///
/// Mouse capture can happen during a handled MouseDown event until MouseUp,
/// or it can be captured explicitly via .
///
bool IsMouseCaptured { get; }
///
/// Captures all mouse events to this control.
///
///
/// This captures all mouse events until is called.
///
/// Note that not all platforms will allow a mouse capture unless the mouse is currently down.
///
/// true if the mouse was captured, false otherwise.
bool CaptureMouse();
///
/// Releases the mouse capture after a call to .
///
void ReleaseMouseCapture();
///
/// Adds a gesture to the control.
///
/// Gesture to add.
void AddGesture(Gesture item);
///
/// Removes all gestures from the control.
///
void ClearGestures();
///
/// Removes a gesture from the control.
///
/// Gesture to remove.
void RemoveGesture(Gesture item);
}
#endregion
}