 |
|
 |
Good work man, we needed it badly
|
|
|
|
 |
|
 |
Hi,
Thanks for this very useful control!
In my case I needed it to work with a Datasource and so I modfied the code to support this scenario.
I added a new ImageMember property to allow you to specify the name of the item property where the image index is stored, and I also added a new, hidden, DrawMode property to hide this property from the deigner so it can't be changed by the user.
Finally I added support for DataRow/DataRowView items in order to support a DataTable as the Datasource.
using System;
using System.Drawing;
using System.Reflection;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
namespace QISoft.UI.Controls
{
public class ImageComboBoxItem : object
{
#region Fields
private Color forecolor = Color.FromKnownColor(KnownColor.Transparent);
private bool mark = false;
private int imageindex = -1;
private object tag = null;
private string text = null;
#endregion
#region Construction
public ImageComboBoxItem()
{
}
public ImageComboBoxItem(string Text)
{
text = Text;
}
public ImageComboBoxItem(string Text, int ImageIndex)
{
text = Text;
imageindex = ImageIndex;
}
public ImageComboBoxItem(string Text, int ImageIndex, bool Mark)
{
text = Text;
imageindex = ImageIndex;
mark = Mark;
}
public ImageComboBoxItem(string Text, int ImageIndex, bool Mark, Color ForeColor)
{
text = Text;
imageindex = ImageIndex;
mark = Mark;
forecolor = ForeColor;
}
public ImageComboBoxItem(string Text, int ImageIndex, bool Mark, Color ForeColor, object Tag)
{
text = Text;
imageindex = ImageIndex;
mark = Mark;
forecolor = ForeColor;
tag = Tag;
}
#endregion
#region Properties
public Color ForeColor
{
get
{
return forecolor;
}
set
{
forecolor = value;
}
}
public int ImageIndex
{
get
{
return imageindex;
}
set
{
imageindex = value;
}
}
public bool Mark
{
get
{
return mark;
}
set
{
mark = value;
}
}
public object Tag
{
get
{
return tag;
}
set
{
tag = value;
}
}
public string Text
{
get
{
return text;
}
set
{
text = value;
}
}
#endregion
#region Overrides
public override string ToString()
{
return text;
}
#endregion
}
public class ImageComboBox : System.Windows.Forms.ComboBox
{
#region Fields
private ImageList _imageList = new ImageList();
private String _imageMember = String.Empty;
#endregion
#region Properties
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "value")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public new DrawMode DrawMode
{
get
{
return DrawMode.OwnerDrawFixed;
}
set
{
}
}
[Browsable(true), Category("Data")]
public ImageList ImageList
{
get
{
return _imageList;
}
set
{
_imageList = value;
}
}
[Browsable(true), Category("Data")]
public String ImageMember
{
get
{
return _imageMember;
}
set
{
_imageMember = value;
}
}
#endregion
#region Construction
public ImageComboBox()
{
base.DrawMode = DrawMode.OwnerDrawFixed;
}
#endregion
#region Overrides
protected override void OnDrawItem(DrawItemEventArgs e)
{
e.DrawBackground();
e.DrawFocusRectangle();
Color forecolor = e.ForeColor;
Font font = e.Font;
String text = String.Empty;
Int32 imageIndex = -1;
if (e.Index < 0)
{
text = this.Text;
}
else
{
Object dataItem = this.Items[e.Index];
Type type = dataItem.GetType();
text = dataItem.ToString();
if (type == typeof(ImageComboBoxItem))
{
ImageComboBoxItem item = (ImageComboBoxItem)dataItem;
forecolor = (item.ForeColor != Color.FromKnownColor(KnownColor.Transparent)) ? item.ForeColor : e.ForeColor;
font = item.Mark ? new Font(e.Font, FontStyle.Bold) : e.Font;
imageIndex = item.ImageIndex;
text = item.Text;
}
else if ( type == typeof(DataRow) || type == typeof(DataRowView) )
{
DataRow row = dataItem as DataRow;
if (row == null)
{
DataRowView rowView = dataItem as DataRowView;
row = rowView.Row;
}
if (!String.IsNullOrEmpty(DisplayMember))
{
text = row.Field<String>(DisplayMember);
}
if (!String.IsNullOrEmpty(ImageMember))
{
imageIndex = row.Field<Int32>(ImageMember);
}
}
else
{
if (!String.IsNullOrEmpty(DisplayMember))
{
PropertyInfo propertyInfo = type.GetProperty(this.DisplayMember);
if (propertyInfo != null)
{
String value = propertyInfo.GetValue(dataItem, null) as String;
if (value != null)
{
text = value;
}
}
}
if (!String.IsNullOrEmpty(ImageMember))
{
PropertyInfo propertyInfo = type.GetProperty(_imageMember);
if (propertyInfo != null)
{
Object value = propertyInfo.GetValue(dataItem, null);
value = Convert.ChangeType(value, typeof(Int32));
if (value is Int32)
{
imageIndex = (Int32)value;
}
}
}
}
}
if (-1 < imageIndex && imageIndex < _imageList.Images.Count)
{
this.ImageList.Draw(e.Graphics, e.Bounds.Left, e.Bounds.Top, imageIndex);
}
e.Graphics.DrawString(text, font, new SolidBrush(forecolor), e.Bounds.Left + _imageList.ImageSize.Width, e.Bounds.Top);
base.OnDrawItem(e);
}
#endregion
}
}
|
|
|
|
 |
|
 |
Hi,
Thanks. It is exactly what I was looking for. I need it for commercial application, so can you please specify the license.
Thanks,
gilvini
|
|
|
|
 |
|
 |
Free to use, without mentioning any copyrights.
|
|
|
|
 |
|
 |
Hi
Does anyone know how to keep the autocomplete mode ?
I'm looking for a combobox with an image without lossing the autocomplete mode and the datasource
|
|
|
|
 |
|
 |
Hello,
I like to have an CheckedListBox which has a small image in addition to its text. The image would be different for each line, just like this Combo has. Does anybody know such a control?
|
|
|
|
 |
|
 |
Hi, thank you for made this control and that information.
We have asking to you about the title meaning.
We tryed to append image file such like gif, jpg, and bmp.
But we have to see the following message after that soon,
"let's set image file, it wasn't image file".
Actually, your demo is good working for above working of us.
we never see the above message in Form of yours.
But it is not working in our new made form.
What is deferent between our each form?
What should do we append setting to our form?
We would like that you answer it as soon possible.
regard,
osaru
|
|
|
|
 |
|
 |
What does your code look like ?
|
|
|
|
 |
|
|
 |
|
 |
Does anyone knows the trick to draw the control like a push button when running under Vista?
|
|
|
|
 |
|
 |
Hi
Thanks for the good idea and implementation.
I changed and upgraded the code to VB.Net 2005.
I got it working in C# 2.0, however, got some problem to get it work in VB.Net 2.0
The error I get is
InvalidArgument=Value of '0' is not valid for 'index'.
on the line
Me.ImageList.Draw(e.Graphics, e.Bounds.Left, e.Bounds.Top, item.Imageindex)
During debugging, I noticed that the OnDrawItem event is fired on Form Load (when the combos are populated on Form load) in C#
whereas OnDrawItem is fired only when I click on any combobox in VB.Net
I would think that the event architecture would remain the same whichever language was used?
Any idea?
Shreekar
http://shreekarishere.blogspot.com
|
|
|
|
 |
|
 |
Shoots himself in the foot.:->
I had not specified the Imagelist to be associated with the Combo box - thats why I got the error.
The mystery about the timing of the events in VB & C#, however, still remains...
Shreekar
http://shreekarishere.blogspot.com
|
|
|
|
 |
|
 |
There should be no difference since they bot run on the same CLR and both VB.NET & C#.NET will compile your app to the same format so that's really weird - unless its a problem in the windows forms designer.
|
|
|
|
 |
|
 |
Were you able to reproduce the same behaviour?
Shreekar
http://shreekarishere.blogspot.com
|
|
|
|
 |
|
 |
I didn't install VS.NET 2005 yet, it's lying around but just formatted the PC. I'm currently using VS.NET 2003 and I haven't even installed VB.NET since I always use C# now
|
|
|
|
 |
|
 |
Great control! Definately learned something here.
Just a small suggestion that might be faster. Where you have
// check if item is an ImageComboItem
if (this.Items[e.Index].GetType() == typeof(ImageComboItem))
you could just say
if (this.Items[e.Index] is ImageComboItem)
Hope that helps,
-Matt
Bart: Look at me, I'm a grad student. I'm 30 years old and I made $600 last year.
Marge: Bart, don't make fun of grad students. They've just made a terrible life choice.
|
|
|
|
 |
|
 |
Hi,
I'm trying to display a drop-down combo with avatar images but unfortunately he images appear blurred when drawn by the custom control. All image sizes (80x80) in the ImageList object and the control's Item width and Height etc. should match. Still, while the overall images appear the same size, they still appear blurred.
Can any one shed some light on this please?
|
|
|
|
 |
|
|
 |
|
 |
It's useful for us!
thanks!
|
|
|
|
 |
|
 |
When I override the OnPaint procedure it's never executed at runtime. Why that?
I would like to implement a DropDown behaviour (not DropDownList) with editable combo items.
But then: The image disappears when the drop down list is closed.
Any idea?
Stefan
|
|
|
|
 |
|
 |
The OnPaint is probably not called because you forgot this line:
this.DrawMode = DrawMode.OwnerDrawFixed;
Add this in your constructor and it should do the trick.
|
|
|
|
 |
|
 |
The second combo from the top (imagecombo) only shows text in black. It does not show the icon or different color text. Should it? Is there a way to control the paint of the textbox contents for this comboboxstyle?
|
|
|
|
 |
|
 |
Hello!
Firstly - great code, thank youv ery much for posting it.
I jsut have a slight problem with tabs. To reproduce:
1. Create a tab control with 2 tabs
2. On tab 1 put a control of some kind (text box, or whatever)
3. On the 2nd tab create a couple of imagecombo controls with style set to "DropDown"
4. Populate the combos with image items.
5. Run!
6. Select something from both combos (but afterwards click in the box to ensure none of the text is selected)
7. Switch to first tab.
8. Switch back to 2nd tab.
At this point, both combo boxes appear to have their text selected. But only the first one actually does (it has its cursor in there).
I'm not sure if this is something I've done. Has anyone noticed this behaviour? Any ideas?
Thanks very much!
John
|
|
|
|
 |
|
 |
Sorry, missing one crucial detail - the combo boxes must be either docked (e.g. to the top) or anchored left and right so that they are resizable. Otherwise it works OK.
Do I need to do something with the resize event?
Thanks!
|
|
|
|
 |
|
 |
I've investigated this some more and the problem is nothing to do with the ImageCombo class and will occur with the normal combo class too.
The problem is related to having the "DropDownStyle" set to "DropDown" and then selecting an object from the dropdown list. I've found that this kind of thing will cure it:
private void comboBox2_VisibleChanged(object sender, System.EventArgs e)
{
if (comboBox2.SelectedItem != null)
{
string Value = comboBox2.SelectedItem.ToString();
this.comboBox2.SelectedIndex = -1;
this.comboBox2.Text = Value;
}
}
which could obviously be built into the ImageCombo class. But it does seem like a bodge to me.
Has anyone else got any better ideas?!
Thanks,
John
|
|
|
|
 |