Introduction
Configuring hardware often requires to display and edit bitmasks. Modifying a graphical binary representation is usually easier as modifying a hex value in a textbox. A corresponding tooltip could explain the meaning of each single bit and the user gets a much more better feedback to what he is doing.
I was wondering that I didn't find any control around doing this job. Here is my result as a Windows Forms user control.
1. What the BitmaskCtrl demo does
The demo basically displays two BitmaskCtrl
instances:
- A readonly one on the left simply incrementing its own value.
- A user editable one to the right including a corresponding
PropertyGrid
intended to play with the BitMaskCtrl
properties.
2. BitmaskCtrl readonly mode
- The
BitmaskCtrl
displays the bits in a very simple way. Each bit is displayed as a numbered rectangle. Depending on the control's size, the bits get arranged in rows and columns. The colors used for a set/not set bit are configurable.
- The bits always get laid out in big endian order (in my opinion, a layout in little endian order is not really useful).
- The control is sizable. It includes an automatic layout function; resize the demo application to explore this. This enables the control to display the value in a vertical orientation.
- As the
Value
property is of type UInt64
, the maximum bits supported is 64.
3. BitmaskCtrl edit mode
- The control supports a focus rectangle controlled by mouse moves and by the left/right keys.
- The focused bit is toggled by a mouse click or the space key.
- Toggling more than one bit in a single operation is done by dragging over the control with the mouse. The same is possible by keyboard (use the Ctrl/Shift keys and the left/right keys).
Using the code
Reference the BitmaskCtrl
like any other control in your own form (as shown in the BitmaskDemo files).
Here is a list of the public BitmaskCtrl
properties:
public UInt64 Value
: Gets or sets the value displayed
public int BitCount
: Specifies the count of bits to display (usually this depends on the value's datatype)
public bool BitMSBFirst
: Set to true
, if the most significant bit should be displayed first
public bool BitStartValue
: Set to any offset the least significant bit index should be displayed with (usually 0 or 1)
public bool AutoLayout
: Set to false
to disable the auto layout feature (all bits will be arranged in one single line)
public bool ReadOnly
: Set to true if the user will not be able to change the displayed value
public bool ShowNumbering
: Set to false if the bit indices shouldn't be displayed; some of us may use this control as a clavilux :-)
public Color BackColor
: Specifies the control's back color
public Color ForeColor
: Specifies the numbering text color to display
public Color BitSetColor
: Specifies the color used to display a set bit
public Color BitNotSetColor
: Specifies the color used to display a not set bit
public int SelectedIndex
: Supplies the currently selected bit index (readonly)
Here is a list of the public BitmaskCtrl
events:
public event EventHandler SelectedIndexChanged
: Selected index changed event, useful to create corresponding tooltips. For example:
void BitmaskCtrl_SelectedIndexChanged(object sender, EventArgs e)
{
Console.WriteLine(string.Format("Bit index is {0}"
, ((BitmaskCtrl)sender).SelectedIndex
);
}
public event EventHandler ValueChanged
: Value changed event. For example:
void BitmaskCtrl_ValueChanged(object sender, EventArgs e)
{
Console.WriteLine(string.Format("Value is {0}"
, ((BitmaskCtrl)sender).Value
);
}
Possible extensions to do on the BitmaskCtrl
:
- Replacing the
UInt64
value with the BigInteger
class from .NET 4.0 may extend the control to support any size of values.
Points of interest
The OnPaint
method in a user control is responsible for drawing the complete state of the control. Currently, a LinearGradientBrush
is used to do the coloring on the bit rectangles.
To get the best performance in the OnPaint
method, the LinearGradientbrush
is re-created only if the layout changes.
Maybe you want to modify the drawing code, so do this in BitmaskCtrl.OnPaint(...)
.
History
- 05/24/2011: Initial release.