
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.