Skip to main content

States

States determine which styles (CSS class) and which properties to apply to a widget. During the lifetime of a widget, the state(s) that the widget assumes change dynamically depending on many factors: pointer, property settings, focus, etc.

A widget can assume several states at the same time, i.e. it can be Focused and Hovered at the same time. The state of a widget is usually changed by the widget implementation, but it can also be manipulated by the application:

this.button1.AddState("critical");
this.textBox1.RemoveState("required");

There are some common states that are supported by most widgets, while individual widgets may add their own states. For example, the wisej.web.TabControl.js widget (corresponding to the Wisej.Web.TabControl control) adds states corresponding to the orientation and alignment of the tabs: barTop, barBottom, barRight, barLeft.

States may also get propagated to internal child widgets, in order to allow the child widgets to adapt their behavior and UI to the owner widget's state.

Inheritance and State Order​

An appearance's inherit field selects its base appearance. Wisej resolves the base appearance's default and active states first, then applies the derived appearance's default and active states. Values are combined by property or style key: a later value overrides an earlier value for the same key, while keys that are not redefined remain inherited.

This means that a derived default can override a value supplied by an inherited active state, such as hovered. Use preserveInherited to change this behavior for an individual state.

Preserving Inherited State Values​

Available since: Wisej.NET 4.1.4 and 3.5.39.

preserveInherited is an optional boolean field on a state, alongside properties and styles. It defaults to false, so omitting it keeps the usual inheritance behavior. In the Theme Builder, select a state node to edit this field.

When preserveInherited is true, each property or style defined by that state keeps the inherited value if its effective source is an active non-default state. Otherwise, the local value applies. The rule applies independently to keys in both properties and styles.

On the Default State​

Set the flag on default to override inherited defaults while preserving values supplied by inherited active states. For example:

{
"appearances": {
"input-field": {
"inherit": "textbox",
"states": {
"default": {
"properties": {
"backgroundColor": "#fff4cc"
}
},
"hovered": {
"properties": {
"backgroundColor": "#a7f3d0"
}
}
}
},
"custom-textbox": {
"inherit": "input-field",
"states": {
"default": {
"preserveInherited": true,
"properties": {
"backgroundColor": "#bfdbfe"
}
}
}
}
}
}

The derived custom-textbox uses blue as its default background and the base appearance's green when hovered. Changing the hovered color in input-field also changes the derived appearance without repeating that color.

Widget stateBase input-fieldDerived, flag omitted or falseDerived, flag true
Default onlyYellow (#fff4cc)Blue (#bfdbfe)Blue (#bfdbfe)
HoveredGreen (#a7f3d0)Blue (#bfdbfe)Green (#a7f3d0)

On Other States​

The same rule applies to hovered, focused, and any other state, including composite states. On these states, the local values act as fallbacks for keys that have no inherited active-state value. For example, adding this state to the derived appearance above preserves the inherited green background on hover:

"hovered": {
"preserveInherited": true,
"properties": {
"backgroundColor": "#c4b5fd"
}
}

If the base appearance supplies no active-state background, the local purple value applies, even if the base defines a default background. With the flag omitted or false on this local hovered state, purple overrides the inherited hovered color.

The distinction is where the flag is applied: on default, it lets inherited active states take precedence over local defaults; on another state, it lets inherited active states take precedence over that local state's values. It preserves values from any active inherited non-default state, not just a state with the same name.

Scope and Ordering​

  • The flag affects only the state on which it is set. A later local state can still override a preserved value according to the usual state order.
  • Preservation compares individual keys. Arrays and objects are treated as whole values; the flag does not perform a deep merge or expand shorthand property groups. An inherited null, false, or zero counts as a value.
  • Inheritance is resolved through the base appearance chain. If an intermediate appearance's unflagged default overrides an ancestor's active-state value, a further derived appearance cannot restore that ancestor's value using this flag.
  • The flag does not activate states or change state forwarding or child appearance lookup. A locally defined child appearance needs its own inherit to extend a base child appearance.

Common States​

Here you can find the list of the common (shared) states by most widgets. However, specific widgets may have additional states that are not listed here.

  • default

    Within each appearance, the default state is applied before its active states. The styles and properties defined in the default state may be overridden by the additional states. Inherited appearances are resolved before local states; see Inheritance and State Order.

  • active

    This is the state used by a Window, which correspond to Wisej.Web.Form, when it is active. Usually there can be only one active window.

  • maximized

    The maximized state is applied to maximized Wisej.Web.Form controls.

  • disabled

    This is the state applied to disabled widgets. The built-in themes set the opacity property to render the widget grayed out.

  • hovered

    This state is applied to a widget when the pointer is over the element, and removed when the pointer moves out.

  • checked

    This state is applied to widgets that support a checked state: check boxes, menu items, tree nodes, ...

  • undetermined

    This state is applied to widgets that support the undetermined state: check boxes, tree nodes, ...

  • pressed

    This state is applied to widgets that support the pressed state: buttons, sliders.

    See how the provided themes use this state to emulate the movement of a button when it is pressed:

"pressed":
{
"styles":
{
"backgroundColor": "buttonPressed",
"transform": "translate(1px, 1px)"
},
}
  • focused

    The focused state is applied to all editable widgets when they gain the focus.

  • invalid

    The invalid state is applied to any editable widget when the application sets the Invalid property to true. Typically a theme can render this state by adding a red border, or an icon, or by changing a color on the widget.

  • contextmenu

    The contextmenu state is applied to widgets that have been assigned a contextual menu.

  • vertical

    This state is applied to widgets that support the vertical state: tab control, sliders, scrollbars.

  • horizontal

    This state is applied to widgets that support the horizontal state: tab control, sliders, scrollbars.

  • barTop

    The barTop state is assigned to a tab control widget when tabs are docked to the top, regardless of the orientation.

  • barLeft

    The barLeft state is assigned to a tab control widget when tabs are docked to the left, regardless of the orientation.

  • barRight

    The barRight state is assigned to a tab control widget when tabs are docked to the right, regardless of the orientation.

  • barBottom

    The barBottom state is assigned to a tab control widget when tabs are docked to the bottom, regardless of the orientation.

  • selected

    The selected state is applied to child items when they are selected: list items, tree nodes.

  • sortable
    ****The sortable state is applied to columns that can be sorted by the user.

  • sorted

    The sorted state is applied to columns when they are sorted.

  • sortedAscending

    The sortedAscending state is applied to columns when they are sorted ascending.

  • opened

    The opened state is applied to tree nodes when they expanded.

  • up, down, left, right

    These states are applied to the scrollbar buttons depending on the orientation of the scrollbar.

  • showingPlaceholder

    The showingPlaceholder state is applied to editable controls when they show the placeholder (empty value with watermark text).

  • drag

    The drag state is applied to a widget when it is the target of a drag operation.

Tools​

Many controls in Wisej have a Tools collection to display small icons inside the control that can be connected to custom actions. These tool icons are managed in a widget using the appearance key "ToolContainer".

You can customize the tools in relation to their container using the following states in the ToolContainer appearance.

  • editor

    ComboBox, DateTimePicker, TextBox

  • datagrid

    DataGridView

  • caption

    Form

  • listbox

    ListBox

  • listview

    ListView

  • panel

    Panel

  • treeview

    TreeView

  • calendar

    MonthCalendar