Hi, In vb.neti am having trouble adding a listbox to every cell within the datagridview control, I want the listbox user ontrol to be displayed all the time not in edit mode. I have set the grid up using the link below but this code will only let me add the usercontrol to one cell. http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/0060d78a-a51d-4c03-b305-20627b90b598/Does anyone know if this is even possible to add a listbox/usercontrol to every cell with in the datagridview. Thanks Matt | | mattvb Wednesday, May 20, 2009 11:25 AM | Ok, actually the way I'm using in the test project is not efficient when the DataGridView needs to handle lots of data. The efficient way is to show the editing control once the cell got the focus and enter editing mode. After you've done the change, and left the cell, you can draw a ListBox with selectedValue in the cell. There are several articles showing you the clues on achieving this. Please check out the following articles.
If you have anything hard to understand, please feel free to let me know. Best regards, Bruce Zhou
Please mark the replies as answers if they help and unmark if they don't. - Marked As Answer bymattvb Friday, May 29, 2009 1:50 PM
- Unmarked As Answer bymattvb Friday, May 29, 2009 1:51 PM
- Marked As Answer byBruce.ZhouMSFT, ModeratorFriday, May 29, 2009 10:22 AM
- Unmarked As Answer bymattvb Friday, May 29, 2009 1:50 PM
- Marked As Answer byBruce.ZhouMSFT, ModeratorThursday, June 18, 2009 6:55 AM
-
| | Bruce.Zhou Thursday, May 28, 2009 1:06 PM | Hi mattvb, There's not built-in way to add ListBox to each of the Cell. But there's a workaround. You can create a List of ListBoxes which total number is equal to the Count of the Cells. In the CellPainting event, you can set the location of each ListBox so that you can align the ListBox to each of the cell. Let me know if you have difficulty in implementing this. Best regards, Bruce Zhou Please mark the replies as answers if they help and unmark if they don't. | | Bruce.Zhou Thursday, May 21, 2009 11:23 AM | Hi Bruce.Zhou
Thanks for the quick response just a quick questiion where would i put thelistof listboxs to. As I am going to use a usercontrol colored dotnetlistbox would this be a problem.
Regards Matt | | mattvb Thursday, May 21, 2009 11:57 AM | Hi mattvb, Just define a list controls like List<ListBox> lstListBoxes = new List<ListBox>(). Using this method, you may still need to define a dictionary object to hold the state. Actually, I know another way. That's extending from the DataGridViewCell, then add a ListBox as a class member in the custom DataGridViewCell type. In the OnPaint event, you have the cell location informat, so you can adjust the ListBox to the cell. Here is a solved thread on how to custom column header cells, you can try to do the same with common cells. Please feel free to let me know if there's any problem. Best regards, Bruce Zhou
Please mark the replies as answers if they help and unmark if they don't. | | Bruce.Zhou Thursday, May 21, 2009 12:15 PM | Hi,
Is there no way to add a user control to each cell, I can add one but it will not let me add more than one with the other one staying in place. I have build a dotnet listbox which can drag and drop between each other, like a day planner sort of thing.
Regards Matt | | mattvb Thursday, May 21, 2009 12:42 PM | Did you mean you want to add two or more UserControls into the cell? I think it can be done, the trick is still the same. Adjust the location of the UserControls so that they look like contained in a cell. Best regards, Bruce Zhou Please mark the replies as answers if they help and unmark if they don't. | | Bruce.Zhou Thursday, May 21, 2009 1:01 PM | Sorry about that, what I mean is to have one usercontrol in every cell on the datagridview. From all the samples does look like it is possible, i have done it before using sourcegrid control devage, using the code below not sure if there is a way to do it in the datagridview.
Dim DataGridListBox As New DotNetListBox
Grid1(y, x) = New SourceGrid3.Cells.Real.CellControl(DataGridListBox)
DataGridListBox = Nothing
Thanks
Regards Matt | | mattvb Thursday, May 21, 2009 1:32 PM | Yes, that's possible. Please check out the link I've given. You may get some clues. Best regards, Bruce Zhou Please mark the replies as answers if they help and unmark if they don't.- Unmarked As Answer bymattvb Tuesday, May 26, 2009 8:50 PM
- Marked As Answer bymattvb Thursday, May 21, 2009 4:35 PM
-
| | Bruce.Zhou Thursday, May 21, 2009 2:27 PM | What iam trying to do Populate a grid with usercontrol listboxs.
Thanks it works now, but i have few problems, intheexample abovefor some reason the ColumnIndex of the first column is always that last column, second column is fine andall other columns just column 0, do you know why this is.
Any idea on how i could make it add the rows correctly not been able to work it out as of yet.
Also when scrolling theusercontrol does not move corectly, it does not move of the screen as it would if it was a text box.
Regards Matt | | mattvb Wednesday, May 27, 2009 7:55 PM | Hi mattvb, Would you please provide the code showing how you are doing? The usercontrol does not move correctly, to solve this, it might need to invalidate the DataGridView after a scroll. Best regards, Bruce Zhou Please mark the replies as answers if they help and unmark if they don't. | | Bruce.Zhou Thursday, May 28, 2009 8:31 AM | Hi Bruce,
It will not let me attach the whole code i will put it in two messages.
Imports
System
Imports
System.Data
Imports
System.Drawing
Imports
System.Collections
Imports
System.ComponentModel
Imports
System.Windows.Forms
Imports
DataGridCallPlanner.PulsePlanner.xListBox
Namespace
PulsePlanner
Partial Public Class Form1
Inherits Form
Private components As System.ComponentModel.IContainer
Public NUMOFENGINEERS As Integer
Public NUMOFDAYS As Integer
Public dtEngineers As DataTable
Public StartDate As Date
Public EndDate As Date
' ("Provider=SQLNCLI.1;Data Source=XPSERVER\SQLEXPRESS;Persist Security Info=True;Password=198123;User ID=sa;Initial Catalog=PulsePlanner_SQL")
Public ConnectionString As String = ("Data Source=XPSERVER\SQLEXPRESS;Persist Security Info=True;Password=198123;User ID=sa;Initial Catalog=PulsePlanner_SQL")
Public con As SqlClient.SqlConnection
Public Sub New()
InitializeComponent()
AddHandler Me.Load, AddressOf Form1_Load
End Sub
Private headerComboBox As Dictionary(Of [String], ComboBox) = New Dictionary(Of String, ComboBox)()
Friend WithEvents DataGridView1 As System.Windows.Forms.DataGridView
Private Sub InitializeComponent()
Me.DataGridView1 = New System.Windows.Forms.DataGridView
CType(Me.DataGridView1, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SuspendLayout()
'
'DataGridView1
'
Me.DataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize
Me.DataGridView1.Location = New System.Drawing.Point(12, 31)
Me.DataGridView1.Name = "DataGridView1"
Me.DataGridView1.Size = New System.Drawing.Size(718, 298)
Me.DataGridView1.TabIndex = 0
'
'Form1
'
Me.ClientSize = New System.Drawing.Size(885, 362)
Me.Controls.Add(Me.DataGridView1)
Me.Name = "Form1"
CType(Me.DataGridView1, System.ComponentModel.ISupportInitialize).EndInit()
Me.ResumeLayout(False)
End Sub
'start of my code - here goes
Private dt As New DataTable()
Private dtJobs As New DataTable
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.DataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing
Me.DataGridView1.ColumnHeadersHeight = 25
'Me.DataGridView1.ColumnHeadersHeight = Me.DataGridView1.ColumnHeadersHeight * 2
Me.DataGridView1.RowCount = 5
' Me.DataGridView1.ColumnCount = 5
Me.DataGridView1.Rows(0).Height = 100
'GetEngineerData()
For x As Integer = 1 To 10 ' NUMOFENGINEERS - 1
Dim col1 As New DataGridColumnListbox()
Me.DataGridView1.Columns.Add(col1)
Next
'For y As Integer = 1 To 3
' Dim row1 As New DataGridColumnListbox()
' Me.DataGridView1.Rows.Add(row1)
'Next
'Me.DataGridView1.Rows.Add(col1)
' AddHandler Me.Paint, AddressOf Form1_Paint
End Sub
Private Sub GetEngineerData()
Dim strSQL As String = ("SELECT * FROM tblEngineers") ' WHERE ""JOBDATE"" BETWEEN '" & FirstDate.ToString("MM/dd/yyyy") & "' AND '") + LastDate.ToString("MM/dd/yyyy") & "' ORDER BY ""JOBDATE"" ASC"
Dim ds As DataSet = ExecuteDataSet(ConnectionString, CommandType.Text, strSQL)
dtEngineers = ds.Tables(0)
NUMOFENGINEERS = (dtEngineers.Rows.Count.ToString())
End Sub
Private Sub UpdateAssignedCalls()
'Dim strSQLUpdate As String
'set xDropTarget Dim c As Control = New xListBox
'Dim ps As Point = Grid1.PointToClient(MousePosition)
'Dim SourceGridPos As SourceGrid3.Position = Grid1.PositionAtPoint(ps)
' xDropTarget = GetXlistbox(SourceGridPos.Row, SourceGridPos.Column)
Dim myConnection As SqlClient.SqlConnection
Dim myCommand As SqlClient.SqlCommand
Dim ra As Integer
myConnection =
New SqlClient.SqlConnection(ConnectionString)
'you need to provide password for sql server
myConnection.Open()
myCommand =
New SqlClient.SqlCommand("Update tblAssignedJobs Set EngineerID='5' where Engineer='Matt'", myConnection)
ra = myCommand.ExecuteNonQuery()
MessageBox.Show(
"Records affected" & ra)
myConnection.Close()
End Sub
'Private Sub btnFillJobs_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnFillJobs.Click
' GetJobData()
'End Sub
'SQL Dataset Reader
Public Function ExecuteDataSet(ByVal connectionString As String, ByVal commandType As CommandType, _
ByVal commandText As String) As DataSet
Dim adapter As New SqlClient.SqlDataAdapter(commandText, connectionString)
With adapter.SelectCommand
.CommandType = commandType
End With
Dim data As New DataSet
adapter.Fill(data)
Return data
End Function
End Class
| | mattvb Thursday, May 28, 2009 9:01 AM |
Public Class TextBoxAndCheckBoxHeaderCell
Inherits DataGridViewColumnHeaderCell
Private Enum SortType
ASC
DesC
None
End Enum
Public uc As New UserControl1
Private sType As SortType
Protected Overloads Overrides Sub OnClick(ByVal e As DataGridViewCellEventArgs)
MyBase.OnClick(e)
If sType = SortType.None Then
sType = SortType.ASC
ElseIf sType = SortType.ASC Then
sType = SortType.DesC
Else
sType = SortType.ASC
End If
End Sub
Public Sub New()
AddHandler uc.MouseClick, AddressOf uc_MouseClick
AddHandler uc.MouseClick, AddressOf uc_ListboxMouseClick
sType = SortType.None
End Sub
Private Sub uc_MouseClick(ByVal sender As Object, ByVal e As MouseEventArgs)
Me.OnClick(New DataGridViewCellEventArgs(Me.ColumnIndex, Me.RowIndex))
MsgBox(
"Clicked " & Me.ColumnIndex & " " & Me.RowIndex)
End Sub
Private Sub uc_ListboxMouseClick(ByVal sender As Object, ByVal e As MouseEventArgs)
Me.OnClick(New DataGridViewCellEventArgs(Me.ColumnIndex, Me.RowIndex))
MsgBox(
"Clicked Istbox " & Me.ColumnIndex & " " & Me.RowIndex)
End Sub
Protected Overloads Overrides Sub Paint(ByVal graphics As Graphics, ByVal clipBounds As Rectangle, _
ByVal cellBounds As Rectangle, ByVal rowIndex As Integer, ByVal dataGridViewElementState As _
DataGridViewElementStates,
ByVal value As Object, ByVal formattedValue As Object, ByVal errorText As String, _
ByVal cellStyle As DataGridViewCellStyle, ByVal advancedBorderStyle As DataGridViewAdvancedBorderStyle, _
ByVal paintParts As DataGridViewPaintParts)
'MsgBox("RUN")
MyBase.Paint(graphics, clipBounds, cellBounds, rowIndex, dataGridViewElementState, value, _
formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts)
Me.uc.Location = New Point(cellBounds.Left, cellBounds.Top + 25)
Me.uc.Height = (cellBounds.Height + 50)
Me.uc.Width = cellBounds.Width - 2
End Sub
End Class
Public Class DataGridColumnListbox
Inherits DataGridViewTextBoxColumn
'Inherits DataGridViewTextBoxCell
Private headerCell1 As New TextBoxAndCheckBoxHeaderCell()
Public Sub New()
Me.CellTemplate = New DataGridViewTextBoxCell()
Me.HeaderCell = headerCell1
End Sub
'when the column is just attached to the DataGridView, we add the controls to the dataGridView.
Protected Overloads Overrides Sub OnDataGridViewChanged()
If Me.DataGridView IsNot Nothing Then
Me.DataGridView.Controls.Add(headerCell1.uc)
End If
End Sub
Public ReadOnly Property HeaderCellEx() As TextBoxAndCheckBoxHeaderCell
Get
Return Me.HeaderCell
End Get
End Property
End Class
End
Namespace | | mattvb Thursday, May 28, 2009 9:03 AM | I have removed my custom usercontrol and just put a startand usercontrol with a listbox. | | mattvb Thursday, May 28, 2009 9:04 AM | Hi mattvb, The thread I suggest to you is to add a custom column header for DataGridView, but not for the general cells. please download this test project , and see if it's the effect is what you want. Note that, the project is for demonstrating purpose, and is not complete and may contain many errors. I'm posting this test project only want to confirm if it's what you want. Best regards, Bruce Zhou
Please mark the replies as answers if they help and unmark if they don't. | | Bruce.Zhou Thursday, May 28, 2009 12:40 PM | Yes, this is what i'm trying to do.
Thanks | | mattvb Thursday, May 28, 2009 12:57 PM | Ok, actually the way I'm using in the test project is not efficient when the DataGridView needs to handle lots of data. The efficient way is to show the editing control once the cell got the focus and enter editing mode. After you've done the change, and left the cell, you can draw a ListBox with selectedValue in the cell. There are several articles showing you the clues on achieving this. Please check out the following articles.
If you have anything hard to understand, please feel free to let me know. Best regards, Bruce Zhou
Please mark the replies as answers if they help and unmark if they don't. - Marked As Answer bymattvb Friday, May 29, 2009 1:50 PM
- Unmarked As Answer bymattvb Friday, May 29, 2009 1:51 PM
- Marked As Answer byBruce.ZhouMSFT, ModeratorFriday, May 29, 2009 10:22 AM
- Unmarked As Answer bymattvb Friday, May 29, 2009 1:50 PM
- Marked As Answer byBruce.ZhouMSFT, ModeratorThursday, June 18, 2009 6:55 AM
-
| | Bruce.Zhou Thursday, May 28, 2009 1:06 PM | I am working on rebuilding the test project to perform what i whateda 25 X 25 datagridview full of listbox usercontrol. Below is the code for scroll event up and down how would i make it work for left and right, tried lots of differents things but cannot get it to work. I have populated the grid with the right amount of listbox's but cannot get the horzontal scroll bar to work correctly.
Private Sub dgv_Scroll(ByVal sender As Object, ByVal e As ScrollEventArgs)'up & down For i As Integer = 0 To Me.dgv.RowCount - 1 If i >= Me.dgv.FirstDisplayedScrollingRowIndex AndAlso i < Me.dgv.DisplayedRowCount(True) Then TryCast(Me.dgv.Rows(i).Cells(0), DataGridViewListBoxCell).EditingControl.Visible = True Else TryCast(Me.dgv.Rows(i).Cells(0), DataGridViewListBoxCell).EditingControl.Visible = False End If Next End Sub
Thanks in advance. Matt | | mattvb Friday, May 29, 2009 1:55 PM | Hi mattvb, As I said before, the test project is used only for demonstrating purpose. If there are many cells in the DataGridView, the application will be very slow using that way. So I hope you can implement one by referring to the above two links. The code in the scroll event handler is hide the corresponding cell editing controls once those cells are out of view. And the above code just handle the verticall scrolling. In case you are interested in the test project, you can try to do the following changes to handle horizontal scrolling: void dgv_Scroll(object sender, ScrollEventArgs e) { //handle verticall scroll for (int i = 0; i < this.dgv.RowCount; i++) { if (i >= this.dgv.FirstDisplayedScrollingRowIndex && i < this.dgv.DisplayedRowCount(true)) { (this.dgv.Rows[i].Cells[0] as DataGridViewListBoxCell).EditingControl.Visible = true; } else { (this.dgv.Rows[i].Cells[0] as DataGridViewListBoxCell).EditingControl.Visible = false; } } //handle horizontal scroll for (int j = 0; j < this.dgv.ColumnCount; j++) { if (j >= this.dgv.FirstDisplayedScrollingColumnIndex && j<dgv.DisplayedColumnCount(true)) { for(int i=0;i<this.dgv.RowCount;i++) (this.dgv.Rows[i].Cells[j] as DataGridViewListBoxCell).EditingControl.Visible = true; } else { for (int i = 0; i < this.dgv.RowCount; i++) (this.dgv.Rows[i].Cells[j] as DataGridViewListBoxCell).EditingControl.Visible = false; } } } Best regards, Bruce Zhou
Please mark the replies as answers if they help and unmark if they don't.- Edited byBruce.ZhouMSFT, ModeratorSaturday, May 30, 2009 1:09 AM
-
| | Bruce.Zhou Saturday, May 30, 2009 1:04 AM | Hi,
I believe this is a similar problem. I am trying to do a super simple DataGridViewRichTextCell. The cellwill not have editing or resizing. However, this will have the ability to cut/copy and click a link (e.g. the basic functions of a RichTextBox). If I create the very simple class below, it works 95% of the way, HOWEVER, after there are a few rows in the table, the paint method keeps getting called. Even after the form has rendered, the paint method is continuously called creating a strange flickering and VERY slow performance. From trial and error, I know that adding the RichTextBox to the DataGridView.Controls is related to the problem.
Do you have any ideas?
Thanks!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
namespace SecureNote.Display
{
class MinimalRichTextBoxCell : DataGridViewCell
{
private RichTextBox _richTextBox = null;
protected override System.Drawing.Rectangle GetContentBounds(System.Drawing.Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex)
{
//DataGridViewAdvancedBorderStyle style;
//DataGridViewElementStates states;
//Rectangle rectangle;
if (cellStyle == null)
{
throw new ArgumentNullException("cellStyle");
}
if (((base.DataGridView == null) || (rowIndex < 0)) || (base.OwningColumn == null))
{
return Rectangle.Empty;
}
// object obj2 = this.GetValue(rowIndex);
// object formattedValue = this.GetFormattedValue(obj2, rowIndex, ref cellStyle, null, null, DataGridViewDataErrorContexts.Formatting);
return this.DataGridView.GetCellDisplayRectangle(this.ColumnIndex, this.RowIndex, true);
// return base.GetContentBounds(graphics, cellStyle, rowIndex);
}
protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
{
base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
if (_richTextBox == null || _richTextBox.IsDisposed)
_richTextBox = new RichTextBox();
_richTextBox.Rtf = (string)value;
this.PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle);
Rectangle internalCellsBounds = cellBounds;
_richTextBox.BackColor = this.Style.BackColor;
_richTextBox.ForeColor = this.Style.ForeColor;
_richTextBox.Location = new Point(cellBounds.Left, cellBounds.Top);
_richTextBox.Size = new Size(cellBounds.Width, cellBounds.Height);
_richTextBox.Refresh();
this.DataGridView.Controls.Add(_richTextBox);
}
}
}
| | jmauster Sunday, July 12, 2009 9:31 PM |
|