|
using System;
using System.Drawing;
using System.Drawing.Design;
using System.Windows.Forms;
using System.Windows.Forms.Design;
using System.ComponentModel;
namespace Pajocomo.Drawing.Design
{
/// <summary>
/// Implements a custom type editor for selecting an enumeration from in a list.
/// <seealso cref="U:http://www.codeproject.com/cs/miscctrl/flagseditor.asp">A flag editor</seealso>
/// </summary>
public class FlagsEditor : System.Drawing.Design.UITypeEditor
{
/// <summary>
/// Internal class used for storing custom data in listviewitems
/// </summary>
internal class FlagItem
{
/// <summary>
/// Initializes a new instance of the <see cref="FlagItem"/> class.
/// </summary>
/// <param name="str">The string to display in the <c>ToString</c> method.
/// It will contains the name of the flag</param>
/// <param name="value">The integer value of the flag</param>
/// <param name="tooltip">The tooltip to display in the <see cref="CheckedListBox"/></param>
public FlagItem(string str, uint value, string tooltip)
{
this.str = str;
this.value = value;
this.tooltip = tooltip;
}
private string str;
private uint value;
/// <summary>
/// Gets the int value for this item
/// </summary>
public uint Value
{
get{return value;}
}
private string tooltip;
/// <summary>
/// Gets the tooltip for this item
/// </summary>
public string Tooltip
{
get{return tooltip;}
}
/// <summary>
/// Gets the name of this item
/// </summary>
/// <returns>The name passed in the constructor</returns>
public override string ToString()
{
return str;
}
}
private IWindowsFormsEditorService flagsEditorService = null;
private CheckedListBox flagsListBox;
private ToolTip tooltipControl;
private bool handleLostfocus = false;
/// <summary>
/// Overrides the method used to provide basic behaviour for selecting editor.
/// Shows our custom control for editing the value.
/// </summary>
/// <param name="context">The context of the editing control</param>
/// <param name="provider">A valid service provider</param>
/// <param name="value">The current value of the object to edit</param>
/// <returns>The new value of the object</returns>
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
if ((context != null) && (context.Instance != null) && (provider != null))
{
this.flagsEditorService = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
if (this.flagsEditorService != null)
{
// Create a CheckedListBox and populate it with all the enum values
this.flagsListBox = new CheckedListBox();
this.flagsListBox.BorderStyle = BorderStyle.FixedSingle;
this.flagsListBox.CheckOnClick = true;
this.flagsListBox.MouseDown += new MouseEventHandler(this.FlagsListBox_MouseDown);
this.flagsListBox.MouseMove += new MouseEventHandler(this.FlagsListBox_MouseMoved);
this.tooltipControl = new ToolTip();
this.tooltipControl.ShowAlways = true;
// Get the int value of the current enum value (the one being edited)
uint uintEdited = (uint)Convert.ChangeType(value, typeof(uint));
foreach(string flagName in Enum.GetNames(context.PropertyDescriptor.PropertyType))
{
// Get the enum value
object flagValue = Enum.Parse(context.PropertyDescriptor.PropertyType, flagName);
// Get the uint value
uint uintValue = (uint) Convert.ChangeType(flagValue, typeof(uint));
if (uintValue != 0)
{
// Get the description attribute for this field
System.Reflection.FieldInfo fi = context.PropertyDescriptor.PropertyType.GetField(flagName);
DescriptionAttribute[] attrs = (DescriptionAttribute[]) fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
// Store the the description
string tooltip = attrs.Length > 0 ? attrs[0].Description : null;
// Creates a FlagItem that stores the name, the int value and the tooltip
FlagItem flagItem = new FlagItem(flagValue.ToString(), uintValue, tooltip);
// Get the checkstate from the value being edited
bool checkedItem = (uintEdited & uintValue) > 0;
// Add the item with the right check state
this.flagsListBox.Items.Add(flagItem, checkedItem);
}
}
// Show our CheckedListbox as a DropDownControl.
// This methods returns only when the dropdowncontrol is closed
this.flagsEditorService.DropDownControl(this.flagsListBox);
// Get the sum of all checked flags
uint uintResult = 0;
foreach(FlagItem flagItem in this.flagsListBox.CheckedItems)
{
uintResult |= flagItem.Value;
}
// return the right enum value corresponding to the result
return Enum.ToObject(context.PropertyDescriptor.PropertyType, uintResult);
}
}
return value;
}
/// <summary>
/// Shows a dropdown icon in the property editor
/// </summary>
/// <param name="context">The context of the editing control</param>
/// <returns><see cref="UITypeEditorEditStyle.DropDown"/></returns>
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.DropDown;
}
/// <summary>
/// When got the focus, handle the lost focus event.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="System.Windows.Forms.MouseEventArgs"/> instance containing the event data.</param>
private void FlagsListBox_MouseDown(object sender, MouseEventArgs e)
{
if(!this.handleLostfocus && this.flagsListBox.ClientRectangle.Contains(this.flagsListBox.PointToClient(new Point(e.X, e.Y))))
{
this.flagsListBox.LostFocus += new EventHandler(this.FlagsListBox_LostFocus);
this.handleLostfocus = true;
}
}
/// <summary>
/// Occurs when the mouse is moved over the checkedlistbox.
/// Sets the tooltip of the item under the pointer
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="System.Windows.Forms.MouseEventArgs"/> instance containing the event data.</param>
private void FlagsListBox_MouseMoved(object sender, MouseEventArgs e)
{
int index = this.flagsListBox.IndexFromPoint(e.X, e.Y);
if(index >= 0)
{
this.tooltipControl.SetToolTip(this.flagsListBox, ((FlagItem)(this.flagsListBox.Items[index])).Tooltip);
}
}
/// <summary>
/// Close the dropdowncontrol when the user has selected a value
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
private void FlagsListBox_LostFocus(object sender, EventArgs e)
{
if (this.flagsEditorService != null)
{
this.flagsEditorService.CloseDropDown();
}
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.