|
This control is wonderful. However in my case I needed to use IList as DataSource.
Although I have found a working solution but am not very satisfied with it. WIll be working more on it. Is there anyone facing the same problem? or may be author would like to enhance the control.
Here is my implementation of in OnDrawItem of DataGridViewMultiColumnComboEditingControl
if(currentRow!=null)
{
}
else
{
string currentText = GetItemText(Items[e.Index]);
SolidBrush normalBack = new SolidBrush(Color.White);
e.Graphics.FillRectangle(normalBack, rec);
if (DroppedDown && !(Margin.Top == rec.Top))
{
Type objectType = objCurrentItem.GetType();
PropertyInfo propertyDisplay = objectType.GetProperty(this.DisplayMember);
PropertyInfo propertyValue = objectType.GetProperty(this.ValueMember);
PropertyInfo[] properties = new PropertyInfo[] { propertyValue, propertyDisplay };
int currentOffset = rec.Left;
SolidBrush HightlightedBack = new SolidBrush(System.Drawing.SystemColors.Highlight);
if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
{
e.Graphics.FillRectangle(HightlightedBack, rec);
}
bool addBorder = false;
foreach (PropertyInfo p in properties)
{
string value = p.GetValue(objCurrentItem, null).ToString();
if (addBorder)
{
SolidBrush gridBrush = new SolidBrush(Color.Gray);
long linesNum = lineWidth;
while (linesNum > 0)
{
linesNum--;
Point first = new Point(rec.Left + currentOffset, rec.Top);
Point last = new Point(rec.Left + currentOffset, rec.Bottom);
e.Graphics.DrawLine(new Pen(gridBrush), first, last);
currentOffset++;
}
}
else
{
addBorder = true;
}
SizeF extent = e.Graphics.MeasureString(value, e.Font);
decimal width = (decimal)extent.Width;
Rectangle textRec = new Rectangle(currentOffset, rec.Y, (int)decimal.Ceiling(width), rec.Height);
if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
{
SolidBrush HightlightedText = new SolidBrush(System.Drawing.SystemColors.HighlightText);
e.Graphics.FillRectangle(HightlightedBack, currentOffset, rec.Y, fixedAlignColumnSize, extent.Height);
e.Graphics.DrawString(value, e.Font, HightlightedText, textRec);
}
else
{
e.Graphics.FillRectangle(normalBack, currentOffset, rec.Y, fixedAlignColumnSize, extent.Height);
e.Graphics.DrawString(value, e.Font, NormalText, textRec);
}
currentOffset += fixedAlignColumnSize;
}
}
else
{
e.Graphics.DrawString(currentText, e.Font, NormalText, rec);
}
}
|
|
|
|
|
I am useing VB2005. In my application I have added one unbound datagridview. I have added one combox cell with some values like "America","Australia","India","Indonesia" etc. Now I want when the user press any key on the combobox, the nearest matches will be shown by droping down. For example if the user press "A or a", the combobox cell will show both "America","Australia". Please help me by providing the code.
|
|
|
|
|
Hi!
I didn't understand from your question if this is in scope of my sample or not.
Anyway, if I understood you good, you mean you want auto complete features in your DataGridView combo cell.
I think the following forum discussing can help you:
http://www.codeguru.com/FORUM/showthread.php?t=404089[^]
I hope it helps you
Issahar
|
|
|
|
|
Great job and very useful. Is there a way to display the column headers on the combobox? I know how to do this when extending the combo box but here you have extended the datagridviewComboBoxColumn.
maryjo
|
|
|
|
|
Hello, Maryjo!
Thanks for compliments
I didn't think about that in this solution.
I used the item owner draw so I didn't redraw the whole combobox but only items
May be the add first item the will be empty and redraw it in owver draw as titles? I think it may work but it is a little bit ugly solution
IssaharNoam
|
|
|
|
|
I have struggled to find code that works. I saw yours, and am trying it. But it seems that when I select an item from the mult-column drop down list, it automatically sorts. I don't want it to.
Also, if I select an item from the multi-column drop down list, and then immediately select an item from the row below, it errors out.
My two questions?
1. How to prevent auto sorting?
2. How to prevent error when selecting first row, then item on second row.
thanks,
arevans
|
|
|
|
|
Sorry for delay in my response. I uploaded now fixed version that working much better, you invited to try
Issahar
|
|
|
|
|
Hello Issahar:
Thanks for sharing your approach.
I want to use your control to display all the combobox items in a datagridview cell with only one row.
My datagridview will permit to the user to add rows on demand, and we need to show all the items in the combobox.
Right now the combobox only show the items that are being displayed on the datagridview.
Appreciate your help to achieve that.
Thanks in advance
David
|
|
|
|
|
I uploaded now fixed version that working much better, you invited to try
It give the solution for your question
Issahar
|
|
|
|
|
Has anyone taken this code and fleshed out this control a bit more?
If so, can I please see your source code?
|
|
|
|
|
|
I uploaded now fixed version that working much better, you invited to try
Issahar
|
|
|
|
|
Hello Issahar,
Can you please help me with the multiline combobox issue?
I would be pleased if you can send me some sample code to my email kaandemirtas@gmail.com
Thanks in advance.
Best regards,
Kaan Demirtas
Istanbul-TURKEY
|
|
|
|
|
I uploaded now fixed version that working much better, you invited to try
Issahar
|
|
|
|
|
I've tried so hard for a whole day that I still cannot get through this tough problem, somebody please, help me!
I've got the code for Multi Column Combo in DataGridView to solve the problem of displaying multiple data, but I got stuck in displaying some values. Everything goes just fine, but when I tried to display values with the key value diplicated, it doesn't work. For example, I intended to display two rows "bmx2100 |23455 |34" and "bmx2100 |11111 |100", they have the same attribute "bmx2100", but the primary key "23455" and "11111" are different. That was what suppose to be, but now, the program displayed "bmx2100 |23455 |34" twice, and during DEBUG, I print out all the temporary variables and I found that they are all correct! So, what would be the problem!?
This is the Multi Column Combo Cell : http://www.codeproject.com/useritems/Multi_Column_Combo_Cell.asp
And this is the code snippet I modified:
protected override void OnDrawItem(System.Windows.Forms.DrawItemEventArgs e)<br />
{<br />
Rectangle rec = new Rectangle(e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height);<br />
DataGridViewMultiColumnComboColumn column = ownerCell.OwningColumn as DataGridViewMultiColumnComboColumn;<br />
DataTable valuesTbl = column.valuesTbl;<br />
string joinByField = column.joinFieldName;<br />
SolidBrush NormalText = new SolidBrush(System.Drawing.SystemColors.ControlText);<br />
object currentItem = Items[e.Index];<br />
string currentText = GetItemText(currentItem);<br />
<br />
if (e.Index > -1)<br />
{<br />
SolidBrush normalBack = new SolidBrush(Color.White);
e.Graphics.FillRectangle(normalBack, rec);<br />
if (DroppedDown && !(Margin.Top == rec.Top))<br />
{<br />
int currentOffset = rec.Left;<br />
<br />
DataRow[] itemRows = valuesTbl.Select("[" + joinByField + "]='" + currentText + "'");<br />
<br />
SolidBrush HightlightedBack = new SolidBrush(System.Drawing.SystemColors.Highlight);<br />
if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)<br />
{<br />
e.Graphics.FillRectangle(HightlightedBack, rec);<br />
}<br />
StreamWriter sw = new StreamWriter(File.OpenWrite("record"));<br />
foreach (DataRow currentRow in itemRows)<br />
{<br />
bool addBorder = false;<br />
<br />
foreach (object dataRowItem in currentRow.ItemArray)<br />
{<br />
string value = dataRowItem.ToString();
<br />
<br />
<br />
#region DrawLine<br />
if (addBorder)<br />
{<br />
SolidBrush gridBrush = new SolidBrush(Color.Gray);
long linesNum = lineWidth;<br />
while (linesNum > 0)<br />
{<br />
linesNum--;<br />
Point first = new Point(rec.Left + currentOffset, rec.Top);<br />
Point last = new Point(rec.Left + currentOffset, rec.Bottom);<br />
e.Graphics.DrawLine(new Pen(gridBrush), first, last);<br />
currentOffset++;<br />
}<br />
}<br />
else<br />
addBorder = true;<br />
#endregion<br />
<br />
SizeF extent = e.Graphics.MeasureString(value, e.Font);<br />
Rectangle textRec = new Rectangle(currentOffset, rec.Y, (int)extent.Width + 20, rec.Height);<br />
<br />
if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)<br />
{<br />
SolidBrush HightlightedText = new SolidBrush(System.Drawing.SystemColors.HighlightText);<br />
e.Graphics.FillRectangle(HightlightedBack, currentOffset, rec.Y, fixedAlignColumnSize, extent.Height);<br />
e.Graphics.DrawString(value, e.Font, HightlightedText, textRec); sw.Write(value + "|");<br />
}<br />
else<br />
{<br />
e.Graphics.FillRectangle(normalBack, currentOffset, rec.Y, fixedAlignColumnSize, extent.Height);<br />
e.Graphics.DrawString(value, e.Font, NormalText, textRec); sw.Write(value + "|");<br />
}<br />
currentOffset += fixedAlignColumnSize;<br />
}<br />
sw.WriteLine();<br />
}<br />
sw.Close();<br />
}<br />
else<br />
e.Graphics.DrawString(currentText, e.Font, NormalText, rec);<br />
}<br />
}<br />
<br />
}
|
|
|
|
|
Hello!
First, thanks for the interest for this approach.
Second, I succeeded to reproduce that issue you reported.
Third, my exercise is build in a very simple restricted way just to show the approach. That means that I used the combobox first column text be used as unique key for the all the data inside the combobox. It is very far from having a full generic control
Now, after all the excuses are said , in order to fix this behavior (I didn't fully tested this solution so please debug it!),
please make the following change in OnDrawItem method:
1. comment the following row:
DataRow[] itemRows = valuesTbl.Select("[" + joinByField + "]='" + currentText + "'");
2. change the following row:
DataRow currentRow = itemRows[0];
to:
DataRow currentRow = valuesTbl.Rows[e.Index];
Now it will mean that we don't search values in table by key but by their order in combobox.
Please be cautive with that, I didn't test this solution deeply!
This way will cause the joinFieldName property to loose it's meaning!!!
I will try to find time in near future to make this approach being more generic.
I hope it will help you
Thanks
IssaharNoam
|
|
|
|
|
Greetings!
Thank you for your answer and the problem is solved now!
You solve the problem in an easy way. I tried to add another foreach loop to display all the rows selected, but failed at end. It seems that I'm not quite understand the principle here in OnDrawItem function.
Since I'm kinda hurry in getting the answer, I posted a thread in MSDN forum. Luckily, I got an best answer.
Here's the link to the page, this is also the formal way to solve this kind of problem, in my opinion.
Hope this can give you a new idea.
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2208758&SiteID=1[^]
Again, thanks for your help;)
|
|
|
|
|
how do you make it so the Multi Column Combo Cell always shows the drop down arrow?
|
|
|
|
|
nvm figured it out, you just change
newColumn.DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing;
to this:
newColumn.DisplayStyle = DataGridViewComboBoxDisplayStyle.DropDownButton;
|
|
|
|
|
How can this be for BOTH C++ and C#?
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
|
|
|
|
|
maybe C++/CLI...
but i was about to ask the same question if you hadn't.
|
|
|
|
|
Thanks for the comment, I will fix it...
|
|
|
|
|