locked
User control in a datagridview RRS feed

  • Question

  • HI 

    I would like to position a user control (for now just a rectangle with red color) in respect to a datagridview headercell 

    If the headercell location ha X = 100  and I try to use the same X coordinate for the user control (x=100 Y = 30) the last one is not in the rigth position 

    How can I point to the datagridview bound to use the same x coordinate ?


    Wednesday, April 18, 2018 7:58 PM

Answers

  •  If the UserControl is not actually a child control of the DataGridView,  then you need to set the location of the UserControl relative to the DataGridView's Location.  Basically you just need to add the X/Left and Y/Top location of the DataGridView to the Header Cell's location which is relative to the DataGridView.

     You need to take into account any container controls that are involved.  For example,  if the DataGridView is inside another Panel or GroupBox,  you will need to set the UserControl location relative to those too.

    Public Class Form1
        Private WithEvents uc As New UserCtrl
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            uc.Parent = Me
            uc.Visible = False
        End Sub
    
        Private Sub DataGridView1_ColumnHeaderMouseClick(sender As Object, e As DataGridViewCellMouseEventArgs) Handles DataGridView1.ColumnHeaderMouseClick
            If e.Button = MouseButtons.Right Then
                Dim HeaderBounds As Rectangle = DataGridView1.GetCellDisplayRectangle(e.ColumnIndex, -1, False)
                HeaderBounds.X += DataGridView1.Left
                HeaderBounds.Y += DataGridView1.Top
                uc.Bounds = HeaderBounds
                uc.Visible = True
                uc.BringToFront()
            End If
        End Sub
    End Class

     

     Here you can see that when I right-click a header,  the UserControl is set to the bounds of the header cell.


    If you say it can`t be done then i`ll try it

    • Edited by IronRazerz Wednesday, April 18, 2018 10:52 PM
    • Marked as answer by Claudio111 Thursday, April 19, 2018 5:45 AM
    Wednesday, April 18, 2018 10:50 PM

All replies

  • See this thread about a TextBox in DataGridView header Winform textbox lost focus automatically when typing "0" but is fine for other chars as My and IronRazerz code adds a TextBox to a column header.

    Set the Custom control Visible to False 1st. Add the custom control to the DataGridViews control list 2nd. Position it after that. Get the header cell display rectangle for locating the user control and header cell size for sizing the user control. Set the custom controls visiblity to True.

    Code from my code at link. You don't need to set the tag as long as you know the columns index to use.

                    TextBox1.Tag = e.ColumnIndex
                    TextBox1.Location = DataGridView1.GetCellDisplayRectangle(e.ColumnIndex, -1, False).Location
                    TextBox1.Size = DataGridView1.Columns(CInt(TextBox1.Tag)).HeaderCell.Size
                    TextBox1.Visible = True


    La vida loca

    Wednesday, April 18, 2018 8:07 PM
  • it does'nt work

    this is my code

    #Region "filtra"
    		Public Sub ShowFilterPopUp(ByVal pcolumn As Integer)
    			' create a userc control for the column 
    			mColumnIndex = pcolumn
    			Dim uc As New DgvMyFilterUcBaseFilter(mColumnIndex)
    
    			Dim pnt As New Point
    			pnt = SetUcBaseFilterBounds(mColumnIndex)
    			uc.Location = pnt
    			mDataGridView.Controls.Clear()
    			mDataGridView.Controls.Add(uc)
    			'	uc.Label1.Text = mDataGridView.Columns(mColumnIndex).Name
    			uc.BringToFront()
    		End Sub
    #End Region
    
    #Region "Set location for Base Filter"
    		Public Function SetUcBaseFilterBounds(ByVal pcolumn As Integer) As Point
    			mColumnIndex = pcolumn
    			Dim cellBounds As Rectangle = mDataGridView.GetCellDisplayRectangle(mColumnIndex, -1, False)
    			Dim pnt As New Point(cellBounds.Location)
    			Return pnt
    		End Function
    
    #End Region
    

    The User control position in not the rigth one since the headercell  X coordinate point something and the usercontrol X coordinate point to something else

    a

    Wednesday, April 18, 2018 8:41 PM
  •  If the UserControl is not actually a child control of the DataGridView,  then you need to set the location of the UserControl relative to the DataGridView's Location.  Basically you just need to add the X/Left and Y/Top location of the DataGridView to the Header Cell's location which is relative to the DataGridView.

     You need to take into account any container controls that are involved.  For example,  if the DataGridView is inside another Panel or GroupBox,  you will need to set the UserControl location relative to those too.

    Public Class Form1
        Private WithEvents uc As New UserCtrl
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            uc.Parent = Me
            uc.Visible = False
        End Sub
    
        Private Sub DataGridView1_ColumnHeaderMouseClick(sender As Object, e As DataGridViewCellMouseEventArgs) Handles DataGridView1.ColumnHeaderMouseClick
            If e.Button = MouseButtons.Right Then
                Dim HeaderBounds As Rectangle = DataGridView1.GetCellDisplayRectangle(e.ColumnIndex, -1, False)
                HeaderBounds.X += DataGridView1.Left
                HeaderBounds.Y += DataGridView1.Top
                uc.Bounds = HeaderBounds
                uc.Visible = True
                uc.BringToFront()
            End If
        End Sub
    End Class

     

     Here you can see that when I right-click a header,  the UserControl is set to the bounds of the header cell.


    If you say it can`t be done then i`ll try it

    • Edited by IronRazerz Wednesday, April 18, 2018 10:52 PM
    • Marked as answer by Claudio111 Thursday, April 19, 2018 5:45 AM
    Wednesday, April 18, 2018 10:50 PM
  • Thank you Iron for your suggestion.

    In my application I solved the problem just declaring the UC parent

    #Region "filtra"
    		Public Sub ShowFilterPopUp(ByVal pcolumn As Integer)
    			' create a user control for the column 
    			mColumnIndex = pcolumn
    			Dim uc As New DgvMyFilterUcBaseFilter(mColumnIndex)
    			uc.Visible = False
    			uc.Parent = mDataGridView
    
    			Dim pnt As New Point
    			pnt = SetUcBaseFilterBounds(mColumnIndex)
    			uc.Location = pnt
    			mDataGridView.Controls.Clear()
    			mDataGridView.Controls.Add(uc)
    			uc.Visible = True
    			uc.BringToFront()
    		End Sub
    #End Region
    
    #Region "Set location for Base Filter"
    		Public Function SetUcBaseFilterBounds(ByVal pcolumn As Integer) As Point
    			mColumnIndex = pcolumn
    			Dim cellBounds As Rectangle = mDataGridView.GetCellDisplayRectangle(mColumnIndex, -1, False)
    			Dim pnt As New Point(cellBounds.X, (cellBounds.Y + cellBounds.Height + 1))
    			Return pnt
    		End Function
    
    #End Region
    
    End Class


    So I can use the same X Coordinate of every header cell without wondering about panel margin/padding or Datagridview margin

    Thursday, April 19, 2018 5:45 AM