Click here to Skip to main content
Licence 
First Posted 17 Oct 2002
Views 114,571
Bookmarked 58 times

A flag editor

By | 17 Oct 2002 | Article
This piece of code is the implementation of a simple flags editor. It can be used to edit flags in a property grid.

Sample Image - FlagsEditor.gif

Introduction

This editor displays a dropdown control holding a CheckedListBox with all the values of an enumeration.

Using the FlagsEditor

You just have to put the Editor attributes on an enumeration to link it with the FlagsEditor. A Description attribute can also be added to each value. It will be shown as a tooltip on the CheckedListBox items.

Here is a sample.

[Flags,
  Editor(typeof(STUP.ComponentModel.Design.FlagsEditor), 
  typeof(System.Drawing.Design.UITypeEditor))]
public enum EnumerationTest
{
    [Description("Description for the first tested value.")]
    firstValue = 1,
    [Description("Description for the second tested value.")]
    secondValue = 2,
    [Description("Description for the third tested value.")]
    thirdValue = 4
}

How does it work ?

The Editor is just one class that inherits UITypeEditor. The behavior of Editor is controlled by two functions.

GetEditStyle

This function is used for controlling the appearance of the small button in the property grid. In this sample a dropdown arrow will be shown.

public override UITypeEditorEditStyle 
       GetEditStyle(ITypeDescriptorContext context) 
{
    return UITypeEditorEditStyle.DropDown;
}

EditValue

This function is called when the user clicks on the small button.

public override object EditValue(ITypeDescriptorContext context, 
        IServiceProvider provider, object value) 
{
    if (context != null
        && context.Instance != null
        && provider != null) 
    {

        // Get an instance of the IWindowsFormsEditorService. 
        edSvc = (IWindowsFormsEditorService)provider.GetService
                            (typeof(IWindowsFormsEditorService));

        if (edSvc != null) 
        {
            // Create a CheckedListBox
            clb = new CheckedListBox();

            ...

            // Show our CheckedListbox as a DropDownControl. 
            // This methods returns only when
            // the dropdowncontrol is closed
            edSvc.DropDownControl(clb);


            // return the right enum value
            // corresponding to the result
            return ...
        }
    }

    return value;
}

The DropDownControl can be closed by calling the edSvc.CloseDropDown() function.

For a complete example, just download the source file.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Thierry Bouquain

Web Developer

France France

Member



Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralVB.NET Port + Little Extra Feature PinmemberThe_Mega_ZZTer5:16 5 Aug '05  
I ported the code to VB.NET using #Develop's nifty code translation tool for use in my own control... in addition, I added a feature... if the value of a flag is 0 (ie FontStyle.Regular) it will not appear in the listbox. So you can use, for example, the FontStyle enum and Regular will not appear in the list. By unchecking all other flags the 0 value will appear in the textbox. Smile | :)
 
I also included the fixes by James T. Johnson.
 
For those using the C# version who want this feature, here's how to implement it:
 
Find the foreach in the EditValue function and find the IntVal declaration. Right after that line put
 
if (IntVal > 0) {
 
and put the closing } right before the end of the for loop.
 
Here's the VB.NET code... note that the code translator unfortunately strips all comments... sorry for the inconvenience:
 
Imports System
Imports System.Drawing.Design
Imports System.Windows.Forms
Imports System.Windows.Forms.Design
Imports System.ComponentModel
Imports System.Drawing
 
Namespace System.Design
 
Public Class FlagsEditor
Inherits UITypeEditor
 
Friend Class clbItem
 
Public Sub New(ByVal str As String, ByVal value As Integer, ByVal tooltip As String)
Me.str = str
Me._value = value
Me._tooltip = tooltip
End Sub
Private str As String
Private _value As Integer
 
Public ReadOnly Property Value() As Integer
Get
Return _value
End Get
End Property
Private _tooltip As String
 
Public ReadOnly Property Tooltip() As String
Get
Return _tooltip
End Get
End Property
 
Public Overloads Overrides Function ToString() As String
Return str
End Function
End Class
Private edSvc As IWindowsFormsEditorService = Nothing
Private clb As CheckedListBox
Private tooltipControl As ToolTip
 
Public Overloads Overrides Function EditValue(ByVal context As ITypeDescriptorContext, ByVal provider As IServiceProvider, ByVal value As Object) As Object
If Not (context Is Nothing) AndAlso Not (context.Instance Is Nothing) AndAlso Not (provider Is Nothing) Then
edSvc = CType(provider.GetService(GetType(IWindowsFormsEditorService)), IWindowsFormsEditorService)
If Not (edSvc Is Nothing) Then
clb = New CheckedListBox
clb.BorderStyle = BorderStyle.FixedSingle
clb.CheckOnClick = True
AddHandler clb.MouseDown, AddressOf Me.OnMouseDown
AddHandler clb.MouseMove, AddressOf Me.OnMouseMoved
tooltipControl = New tooltip
tooltipControl.ShowAlways = True
For Each name As String In [Enum].GetNames(context.PropertyDescriptor.PropertyType)
Dim enumVal As Object = [Enum].Parse(context.PropertyDescriptor.PropertyType, name)
Dim intVal As Integer = CType(Convert.ChangeType(enumVal, GetType(Integer)), Integer)
If intVal > 0 Then
Dim fi As System.Reflection.FieldInfo = context.PropertyDescriptor.PropertyType.GetField(name)
Dim attrs As DescriptionAttribute() = CType(fi.GetCustomAttributes(GetType(DescriptionAttribute), False), DescriptionAttribute())
Dim tooltip As String
If attrs.Length > 0 Then
tooltip = attrs(0).Description
Else
tooltip = ""
End If
Dim intEdited As Integer = CType(Convert.ChangeType(value, GetType(Integer)), Integer)
Dim item As clbItem = New clbItem(enumVal.ToString, intVal, tooltip)
Dim checkedItem As Boolean = ((intEdited And intVal) = intVal)
clb.Items.Add(item, checkedItem)
End If
Next
edSvc.DropDownControl(clb)
Dim result As Integer = 0
For Each obj As clbItem In clb.CheckedItems
result = result Or obj.Value
Next
Return [Enum].ToObject(context.PropertyDescriptor.PropertyType, result)
End If
End If
Return value
End Function
 
Public Overloads Overrides Function GetEditStyle(ByVal context As ITypeDescriptorContext) As UITypeEditorEditStyle
Return UITypeEditorEditStyle.DropDown
End Function
Private handleLostfocus As Boolean = False
 
Private Sub OnMouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)
If Not handleLostfocus AndAlso clb.ClientRectangle.Contains(clb.PointToClient(New Point(e.X, e.Y))) Then
AddHandler clb.LostFocus, AddressOf Me.ValueChanged
handleLostfocus = True
End If
End Sub
 
Private Sub OnMouseMoved(ByVal sender As Object, ByVal e As MouseEventArgs)
Dim index As Integer = clb.IndexFromPoint(e.X, e.Y)
If index >= 0 Then
tooltipControl.SetToolTip(clb, CType(clb.Items(index), clbItem).Tooltip)
End If
End Sub
 
Private Sub ValueChanged(ByVal sender As Object, ByVal e As EventArgs)
If Not (edSvc Is Nothing) Then
edSvc.CloseDropDown()
End If
End Sub
End Class
End Namespace

Generalcant get the zip file PinsussPaul Ashton1:10 14 Apr '05  
GeneralRe: cant get the zip file PinmemberThe_Mega_ZZTer5:15 5 Aug '05  
GeneralThank You PinmemberDave Mc Kenzie22:26 14 Oct '04  
QuestionHow to use this concept for other types? PinmemberDerSebastian3:29 4 Oct '04  
AnswerRe: How to use this concept for other types? Pinmembereschneider10012:15 9 Nov '05  
GeneralNice Job! Pinmemberglusk9:52 30 Aug '04  
GeneralFlag Editor PinmemberFregate19:10 18 Dec '03  
GeneralRe: Flag Editor PinmemberShyH20:02 26 Jan '04  
GeneralIt took... PinmemberJames T. Johnson1:32 28 May '03  
GeneralRe: It took... PinmemberNnamdi Onyeyiri3:45 28 May '03  
GeneralIgnore the people PinmemberPete Bassett1:16 6 Dec '02  
GeneralRe: Ignore the people PinmemberVirender Sandhu10:28 9 Feb '03  
Questionumm ... I second the ... What is this exactly ? PinsussAnonymous17:17 18 Oct '02  
AnswerRe: umm ... I second the ... What is this exactly ? PineditorJames T. Johnson17:46 18 Oct '02  
GeneralRe: umm ... I second the ... What is this exactly ? PinmemberPhilippe Lhoste6:32 22 Oct '02  
GeneralRe: umm ... I second the ... What is this exactly ? Pinmemberstestagg2:01 10 Jul '08  
Questionumm...what is this exactly? PinmemberMarc Clifton11:13 18 Oct '02  
AnswerRe: umm...what is this exactly? PinmemberEd.Poore5:09 24 Aug '06  
GeneralRe: umm...what is this exactly? PinprotectorMarc Clifton8:07 24 Aug '06  
GeneralRe: umm...what is this exactly? PinmemberEd.Poore8:19 24 Aug '06  
GeneralRe: umm...what is this exactly? Pinmemberpeterchen3:01 11 Apr '07  
General!wow PinmemberNorm Almond7:56 18 Oct '02  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web04 | 2.5.120529.1 | Last Updated 18 Oct 2002
Article Copyright 2002 by Thierry Bouquain
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid