 |
|
 |
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.
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
|
|
|
|
 |
|
 |
would someone be so kind and send me the .zip file
thank you
ashtonpa@bupa.com
|
|
|
|
 |
|
 |
Works fine for me. Try again.
[Edit: Oops, thought the date said "4 Aug" not "14 Apr" hehe.]
|
|
|
|
 |
|
|
 |
|
 |
Hi!
Nice suggestion!
I want to use this concept for ArrayLists!?
How can I replace the description 'Flags' of the Enums for ArrayLists??
Thank you!
|
|
|
|
 |
|
 |
//Bit of a hack, but this is an example using any ArrayList and objects.
//Items should us ToString()
//Still needs some checks, and error handlers
//Eric Schneider
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) {
if (context != null && context.Instance != null && provider != null) {
m_IWindowsFormsEditorService = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
if (m_IWindowsFormsEditorService != null) {
// Create a CheckedListBox and populate it with all the enum values
m_CheckedListBox = new CheckedListBox();
m_CheckedListBox.BorderStyle = BorderStyle.FixedSingle;
m_CheckedListBox.CheckOnClick = true;
m_CheckedListBox.MouseDown += new MouseEventHandler(this.OnMouseDown);
m_CheckedListBox.MouseMove += new MouseEventHandler(this.OnMouseMoved);
//Get the data for master list of items.
ISelectionSources sd=(ISelectionSources)context.Instance;
TypeConverter.StandardValuesCollection data = sd.SelectionData().GetStandardValuesListUsersPortfolioManagers();
//Add master list of items
foreach(object titem in data) {
m_CheckedListBox.Items.Add(titem, false);
}
//Update checked state
if ( value.GetType()==typeof(ArrayList)){
foreach(object uitem in (ArrayList)value) {
m_CheckedListBox.SetItemChecked(m_CheckedListBox.Items.IndexOf(uitem),true);
}
}
// Show our CheckedListbox as a DropDownControl.
m_IWindowsFormsEditorService.DropDownControl(m_CheckedListBox);
ArrayList result =new ArrayList();
for(int t=0;t<=m_CheckedListBox.CheckedItems.Count-1;t++){
result.Add(m_CheckedListBox.CheckedItems[t]);
}
value=result;
return value;
}
}
return value;
}
Schneider
|
|
|
|
 |
|
 |
I routinely have to create custom UITypeEditors for various controls that I create, and this was one that was not yet in my arsenal. You saved me a good bit of coding time.
Oh, and...if you have to ask why you need this component, then you shouldn't be using it.
|
|
|
|
 |
|
 |
Thierry,
Great - it's working (even in VB.NET)
A silly question:
When user unselect ALL check boxes, value in Property Grid cell became equal 0.
How to populate it with an empty string?
Regards, Igor
|
|
|
|
 |
|
 |
U need to add the TypeConvereterAttribute to the propery
and create a class inherited from TypeConverter, which convert to string the right values.
|
|
|
|
 |
|
 |
3 hours and Google to do it, but I finally found your article again.
I also fixed a minor bug that occurs when the enum has members that are defined as being a combination of other members in the enum.
In the code where you set the initial check states change:
bool checkedItem = (intEdited & intVal) > 0;
to:
bool checkedItem = (intEdited & intVal) == intVal;
and
In the code where you create the new value change:
result += obj.Value;
to:
result |= obj.Value;
Otherwise an enum like this:
enum Test
{
ValueA = 1,
ValueB = 2,
ValueC = 4,
ValueAB = ValueA | ValueB }Will result in the initial checks having the combined value being checked if only one of the values is actually set. And when it returns the value it erringly adds values instead of ORing them.
So if you have ValueAB checked, the value returned will be 6 (ValueA + ValueB + ValueAB) where-as the correct value is 3 (ValueAB).
If you don't mind, I'll be using this code in the next version of my Wizard framework[^]. The only changes I made aside from the two fixes above was to change the namespace to match what I use in the framework. I have also included comments that the original code is yours.
James
"I despise the city and much prefer being where a traffic jam means a line-up at McDonald's"
Me when telling a friend why I wouldn't want to live with him
|
|
|
|
 |
|
|
 |
|
 |
who don't know what this is...
Good job.
Pete
Insert Sig. Here!
|
|
|
|
 |
|
 |
Nice job
I have a little different requirements but this example perfectly helps me to develop my editor
|
|
|
|
 |
|
 |
Where would I make use of this code and more importantly why would I use this?
|
|
|
|
 |
|
 |
The purpose of the article is to create a designer for enums with the Flag attribute. Right now if you have an enum with the Flag attribute the designer only lets you choose one of the values; with this designer you can select multiple values.
James
Sig code stolen from David Wulff
|
|
|
|
 |
|
 |
Oooh, I am disappointed.
I thought it was a graphic editor to draw nice national flags...
|
|
|
|
 |
|
|
 |
|
 |
It's Friday. Am I being dense?
Marc
Help! I'm an AI running around in someone's f*cked up universe simulator.
|
|
|
|
 |
|
 |
A very long delayed response, but yes you're being extremely dense. Especially considering your abilities now
Formula 1 - Short for "F1 Racing" - named after the standard "help" key in Windows, it's a sport where participants desperately search through software help files trying to find actual documentation. It's tedious and somewhat cruel, most matches ending in a draw as no participant is able to find anything helpful. - Shog9
Ed
|
|
|
|
 |
|
 |
Ed.Poore wrote: A very long delayed response, but yes you're being extremely dense. Especially considering your abilities now
I'm not even sure I knew what a PropertyGrid was, 4 years ago. I was coming from the MFC/C++ world, and while I still don't use designers, at least now I know what most of the UI components are.
Marc
Thyme In The CountryPeople are just notoriously impossible. --DavidCrow There's NO excuse for not commenting your code. -- John Simmons / outlaw programmer People who say that they will refactor their code later to make it "good" don't understand refactoring, nor the art and craft of programming. -- Josh Smith
|
|
|
|
 |
|
 |
Well you're at the stage where you're
writeDesigner:
this.WriteDesignerForDesigner();
goto writeDesigner;
As of how to accomplish this, have you ever tried Google?
|
|
|
|
 |
|
|
 |
|
 |
!wow, so cool <sigh> it just gets better...
Developing with C++ is like programming by the seat of your pants
|
|
|
|
 |