I'm perhaps not articulating this correctly (and apologies if this is the case), but is anyone aware of a Winforms control that could be used to both represent an integer in binary form, and allow the user to 'switch' every separate bit?
I've clobbered together a rough approach for this - using a CheckListBox control, and a couple of enum lists, adding a checkbox for each bit at design time.
This works, but it's not a neat solution, and I wondered perhaps if there was a neater approach. I may need to repeat the work in other projects, so thought about knocking up a custom control to do this, but if anyone is aware of an existing way to do this, I'd be interested!
I would try this approach:
Make bitwise enum:
[Flags]
public enum MyBits
{
MyFirstBit = 1 << 0,
MySecondBit = 1 << 1,
MyThirdBit = 1 << 2,
};
Now create a custom control based on CheckedListBox which accepts any enum as input. Ue this enum to fill your control with checkboxes. One checkbox per enum:
public partial class EnumEditor : CheckedListBox
{
public EnumEditor()
{
InitializeComponent();
ItemCheck += EnumEditor_ItemCheck;
}
private object _value;
public object Value
{
get
{
return _value;
}
set
{
if (value == null)
throw new ArgumentNullException("Value");
if (!value.GetType().IsEnum)
throw new ArgumentNullException("Value should be enumerable.");
if (value.GetType().GetCustomAttributes(typeof(FlagsAttribute), false).Length == 0)
throw new ArgumentNullException("Value must be marked with [Flags].");
_value = value;
Rebuild();
}
}
public event EventHandler<EnumValueChangeEventArgs> ValueChanged;
protected virtual void OnValueChanged(object value)
{
EventHandler<EnumValueChangeEventArgs> valueChanged = ValueChanged;
if (valueChanged != null)
valueChanged(this, new EnumValueChangeEventArgs { Value = value });
}
private void Rebuild()
{
Items.Clear();
if (_value != null)
{
foreach (object value in Enum.GetValues(_value.GetType()))
Items.Add(value, ((int)_value & (int)value) != 0);
}
}
void EnumEditor_ItemCheck(object sender, ItemCheckEventArgs e)
{
ulong bits = Convert.ToUInt64(_value);
ulong bit = Convert.ToUInt64(Items[e.Index]);
if (e.NewValue == CheckState.Checked)
bits = bits | bit;
else
bits = bits & ~bit;
_value = Enum.ToObject(_value.GetType(), bits);
OnValueChanged(_value);
}
}
public class EnumValueChangeEventArgs : EventArgs
{
public object Value
{
get;
set;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With