281 lines
6.1 KiB
C#
281 lines
6.1 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.ComponentModel;
|
|
using System.Drawing;
|
|
using System.Data;
|
|
using System.Windows.Forms;
|
|
using System.Drawing.Design;
|
|
using System.Windows.Forms.Design;
|
|
|
|
|
|
namespace Volian.Controls.Library
|
|
{
|
|
|
|
public class FlagCheckedListBox : CheckedListBox
|
|
{
|
|
private System.ComponentModel.Container components = null;
|
|
|
|
public FlagCheckedListBox()
|
|
{
|
|
// This call is required by the Windows.Forms Form Designer.
|
|
InitializeComponent();
|
|
|
|
// TODO: Add any initialization after the InitForm call
|
|
|
|
}
|
|
|
|
protected override void Dispose(bool disposing)
|
|
{
|
|
if (disposing)
|
|
{
|
|
if (components != null)
|
|
components.Dispose();
|
|
}
|
|
base.Dispose(disposing);
|
|
}
|
|
|
|
#region Component Designer generated code
|
|
private void InitializeComponent()
|
|
{
|
|
//
|
|
// FlaggedCheckedListBox
|
|
//
|
|
this.CheckOnClick = true;
|
|
|
|
}
|
|
#endregion
|
|
|
|
// Adds an integer value and its associated description
|
|
public FlagCheckedListBoxItem Add(uint v, string c)
|
|
{
|
|
FlagCheckedListBoxItem item = new FlagCheckedListBoxItem(v, c);
|
|
Items.Add(item);
|
|
return item;
|
|
}
|
|
|
|
public FlagCheckedListBoxItem Add(FlagCheckedListBoxItem item)
|
|
{
|
|
Items.Add(item);
|
|
return item;
|
|
}
|
|
|
|
protected override void OnItemCheck(ItemCheckEventArgs e)
|
|
{
|
|
base.OnItemCheck(e);
|
|
|
|
if (isUpdatingCheckStates)
|
|
return;
|
|
|
|
// Get the checked/unchecked item
|
|
FlagCheckedListBoxItem item = Items[e.Index] as FlagCheckedListBoxItem;
|
|
// Update other items
|
|
UpdateCheckedItems(item, e.NewValue);
|
|
}
|
|
|
|
// Checks/Unchecks items depending on the give bitvalue
|
|
protected void UpdateCheckedItems(uint value)
|
|
{
|
|
|
|
isUpdatingCheckStates = true;
|
|
|
|
// Iterate over all items
|
|
for (int i = 0; i < Items.Count; i++)
|
|
{
|
|
FlagCheckedListBoxItem item = Items[i] as FlagCheckedListBoxItem;
|
|
|
|
if (item.value == 0)
|
|
{
|
|
SetItemChecked(i, value == 0);
|
|
}
|
|
else
|
|
{
|
|
|
|
// If the bit for the current item is on in the bitvalue, check it
|
|
if ((item.value & value) == item.value && item.value != 0)
|
|
SetItemChecked(i, true);
|
|
// Otherwise uncheck it
|
|
else
|
|
SetItemChecked(i, false);
|
|
}
|
|
}
|
|
|
|
isUpdatingCheckStates = false;
|
|
|
|
}
|
|
|
|
// Updates items in the checklistbox
|
|
// composite = The item that was checked/unchecked
|
|
// cs = The check state of that item
|
|
protected void UpdateCheckedItems(FlagCheckedListBoxItem composite, CheckState cs)
|
|
{
|
|
|
|
// If the value of the item is 0, call directly.
|
|
if (composite.value == 0)
|
|
UpdateCheckedItems(0);
|
|
|
|
|
|
// Get the total value of all checked items
|
|
uint sum = 0;
|
|
for (int i = 0; i < Items.Count; i++)
|
|
{
|
|
FlagCheckedListBoxItem item = Items[i] as FlagCheckedListBoxItem;
|
|
|
|
// If item is checked, add its value to the sum.
|
|
if (GetItemChecked(i))
|
|
sum |= item.value;
|
|
}
|
|
|
|
// If the item has been unchecked, remove its bits from the sum
|
|
if (cs == CheckState.Unchecked)
|
|
sum = sum & (~composite.value);
|
|
// If the item has been checked, combine its bits with the sum
|
|
else
|
|
sum |= composite.value;
|
|
|
|
// Update all items in the checklistbox based on the final bit value
|
|
UpdateCheckedItems(sum);
|
|
|
|
}
|
|
|
|
private bool isUpdatingCheckStates = false;
|
|
|
|
// Gets the current bit value corresponding to all checked items
|
|
public uint GetCurrentValue()
|
|
{
|
|
uint sum = 0;
|
|
|
|
for (int i = 0; i < Items.Count; i++)
|
|
{
|
|
FlagCheckedListBoxItem item = Items[i] as FlagCheckedListBoxItem;
|
|
|
|
if (GetItemChecked(i))
|
|
sum |= item.value;
|
|
}
|
|
|
|
return sum;
|
|
}
|
|
|
|
Type enumType;
|
|
Enum enumValue;
|
|
|
|
// Adds items to the checklistbox based on the members of the enum
|
|
private void FillEnumMembers()
|
|
{
|
|
foreach (string name in Enum.GetNames(enumType))
|
|
{
|
|
object val = Enum.Parse(enumType, name);
|
|
uint intVal = (uint)Convert.ChangeType(val, typeof(uint));
|
|
|
|
Add(intVal, name);
|
|
}
|
|
}
|
|
|
|
// Checks/unchecks items based on the current value of the enum variable
|
|
private void ApplyEnumValue()
|
|
{
|
|
uint intVal = (uint)Convert.ChangeType(enumValue, typeof(uint));
|
|
UpdateCheckedItems(intVal);
|
|
|
|
}
|
|
|
|
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
|
|
public Enum EnumValue
|
|
{
|
|
get
|
|
{
|
|
object e = Enum.ToObject(enumType, GetCurrentValue());
|
|
return (Enum)e;
|
|
}
|
|
set
|
|
{
|
|
|
|
Items.Clear();
|
|
enumValue = value; // Store the current enum value
|
|
enumType = value.GetType(); // Store enum type
|
|
FillEnumMembers(); // Add items for enum members
|
|
ApplyEnumValue(); // Check/uncheck items depending on enum value
|
|
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|
|
// Represents an item in the checklistbox
|
|
public class FlagCheckedListBoxItem
|
|
{
|
|
public FlagCheckedListBoxItem(uint v, string c)
|
|
{
|
|
value = v;
|
|
caption = c;
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
return caption;
|
|
}
|
|
|
|
// Returns true if the value corresponds to a single bit being set
|
|
public bool IsFlag
|
|
{
|
|
get
|
|
{
|
|
return ((value & (value - 1)) == 0);
|
|
}
|
|
}
|
|
|
|
// Returns true if this value is a member of the composite bit value
|
|
public bool IsMemberFlag(FlagCheckedListBoxItem composite)
|
|
{
|
|
return (IsFlag && ((value & composite.value) == value));
|
|
}
|
|
|
|
public uint value;
|
|
public string caption;
|
|
}
|
|
|
|
|
|
// UITypeEditor for flag enums
|
|
public class FlagEnumUIEditor : UITypeEditor
|
|
{
|
|
// The checklistbox
|
|
private FlagCheckedListBox flagEnumCB;
|
|
|
|
public FlagEnumUIEditor()
|
|
{
|
|
flagEnumCB = new FlagCheckedListBox();
|
|
flagEnumCB.BorderStyle = BorderStyle.None;
|
|
}
|
|
|
|
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
|
|
{
|
|
if (context != null
|
|
&& context.Instance != null
|
|
&& provider != null)
|
|
{
|
|
|
|
IWindowsFormsEditorService edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
|
|
|
|
if (edSvc != null)
|
|
{
|
|
|
|
Enum e = (Enum)Convert.ChangeType(value, context.PropertyDescriptor.PropertyType);
|
|
flagEnumCB.EnumValue = e;
|
|
edSvc.DropDownControl(flagEnumCB);
|
|
return flagEnumCB.EnumValue;
|
|
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
|
|
{
|
|
return UITypeEditorEditStyle.DropDown;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
}
|