 |
|
 |
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
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
 |
|
|
 |
|
 |
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!
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
//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
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
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.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
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
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
U need to add the TypeConvereterAttribute to the propery and create a class inherited from TypeConverter, which convert to string the right values.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
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
|
| Sign In·View Thread·PermaLink | 5.00/5 (2 votes) |
|
|
|
 |
|
|
 |
|
|
 |
|
|
 |
|
|
 |
|
 |
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
|
| Sign In·View Thread·PermaLink | 5.00/5 (1 vote) |
|
|
|
 |
|
|
 |
|
|
 |
|
 |
It's Friday. Am I being dense?
Marc
Help! I'm an AI running around in someone's f*cked up universe simulator.
|
| Sign In·View Thread·PermaLink | 1.00/5 (2 votes) |
|
|
|
 |
|
 |
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
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
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
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
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?
|
| Sign In·View Thread·PermaLink | 5.00/5 (1 vote) |
|
|
|
 |
|
|
 |
|
 |
!wow, so cool <sigh> it just gets better...
Developing with C++ is like programming by the seat of your pants
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |