locked
Datagridview "HideSelection"

    Question

  • I'm using an unbound datagridview to display information, and I need to color-code certain cells to alert the user to status events.  Is there a way to not have the selected row highlighted when the control does not have focus (similar to the VB6 .HideSelection property)?
    Tuesday, January 24, 2006 11:30 PM

All replies

  • I would explore using the DataGridViewx.SelectionChanged method to test your condition and if not met, set the Style.Backcolor to normal - else set Style.Backcolor to the row highlight color.
    Monday, February 06, 2006 9:05 AM
  • I appreciate the suggestion, but I'm not trying to alter the color during selection, I want the highlight to not be shown when the control does not have focus.  I tried setting the selected row to nothing in the LostFocus event but that had no effect. 

    Any other ideas would be welcome :)

    Monday, February 06, 2006 4:03 PM
  • What row selection method are you using? Perhaps row header select would solve your problem.

    If I understand your response to my first suggestion, you want to focus on a cellcontrol and change the color of that cell to highlight something to the user, but you do not want your focus on that cellcontrol to trigger a row select.

    Monday, February 06, 2006 5:45 PM
  • Nope, that's not what I'm trying for.  Sorry if I was unclear.  I have a datagridview that is not bound to anything, I'm adding rows/cells as needed.  The grid is set for FullRowSelect, row headers are not displayed.

    When you click on the grid, it highlights the full row, that's fine.  When you click off of the grid and move focus to another control; a button say, the grid row that you selected remains highlighted (which is a good thing because you might need to know what was selected).  This usually is not a problem, but I'm using the gridview for a status display and some of the grid cells are highlighted different colors to notify the user of various conditions.  Needless to say, if the row remains highlighted the color display is not seen since the color change will not be visible until the highlight is removed (this presents a problem especially for one-row grids).

    I'd like to NOT have to come up with a hack such as adding a dummy row at the bottom, and when the control loses focus saving the current selection to a form-level variable then setting the selected row the dummy row. 

    VB6 and lower's FlexGrid had a ".HideSelection" property which removed the highlight from the grid (without changing the selected row) when the grid did not have focus.  That's what I'm looking for with the DataGridView.  Is there some property, or combination of properties, that can emulate this behavior?

    Monday, February 06, 2006 6:13 PM
  • There is still a HideSelection property, but now it is on the individual cell textbox controls - see

    http://msdn2.microsoft.com/en-us/library/system.windows.forms.datagridviewtextboxeditingcontrol_properties.aspx

    Monday, February 06, 2006 8:55 PM
  • Without testing it, I'm pretty sure that only applies to selected areas within each textbox, not the grid's highlighting of the entire row.  At least as I understand the inherited property.   Accessing the individual cell, I don't see a way to set this property.
    Monday, February 06, 2006 9:12 PM
  • I need to do the same thing in my project, I havent tried this yet but this may do the job, subclass the control, intercept the paint event, interrogate the cell/row/column state and if it is selected override the paint event with one of your own.  I do this at the moment to create custom column and cell types within the datagridview.  Like I say I havent tried this so I have no idea if it will work or how much coding is involved.
    Tuesday, February 14, 2006 9:29 AM
  • I'd posted to the following thread a link to drawing the backgounds (a gradient in this case) on a DataGridView:

    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=246505&SiteID=1

    You should be able to use the same technique.

    Tuesday, February 14, 2006 1:27 PM
  • I'd posted to the following thread a link to drawing the backgounds (a gradient in this case) on a DataGridView:

    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=246505&SiteID=1

    You should be able to use the same technique. There are pre-paint and post-paint events that you can take advantage of.

    Tuesday, February 14, 2006 1:28 PM
  • That's helpful, but rather like wanting to go to the corner store to get a soft drink and then deciding to build an entire car from scratch to accomplish the journey.

    I don't need to do anything special like a gradient or span multiple columns, just have the dang highlight bar disappear when the control does not have focus.  I did play with the example code and on the highlight areas added ".. And Me.ActiveControl.Equals(DataGridView1) ..." to the If's and put a row invalidate (current row index) in the LostFocus event but dang if it didn't still draw the highlightbar when the control was out of focus.

    If anyone has a simple example of just disabling the highlight bar when the control is not in focus I've been unable to find it.

    Tuesday, February 14, 2006 4:26 PM
  • Presumably you have tried setting the selected property to false for each selected row. I'm a bit curious as to why that doesn't work for you. You could do it in the lost focus event, something like:

    Dim r As DataGridViewRow
    For Each r In
    DataGridView1.SelectedRows
        r.Selected =
    False
    Next

    Does that work?

    Tuesday, February 14, 2006 6:46 PM
  • That will indeed, remove the highlight bar, but it does so by removing the user's selection.  I hadn't gone down that road because I need know what was selected so I can process their selection if needed, and saving off what was selected in a form-level variable seemed 'hackish'.  I was hoping for a more eloquent solution.

    Tuesday, February 14, 2006 8:56 PM
  • Use the .Tag property; you don't have to store anything at form level. In the LostFocus event, store the selected setting for each row, and in the gotfocus event, read the tag object, and set the selected property as appropriate.

    Tuesday, February 14, 2006 10:47 PM
  • Did that do what you wanted it to do, or did you find another solution? I'd be interested in the other solution if you have one .

    Thursday, February 16, 2006 11:28 PM
  • Setting the tag property, or setting a form level variable is basically the same thing:  You save off the selection in the lost focus, clear the selection, then restore it in the got focus.  Any later code that needs to know what was selected must also reset the selection to get the information.  This seems kind of silly to me when simply supporting a ".HideSelection" property in the underlying control would be far simpler.  It should be as simple as "if I'm not the active control then don't do this highlight code."

    This process may be okay for an un-bound grid, but I don't think I'd want to try it on a databound grid with several thousand records.  Currently I'm just living with the highlight always being displayed =/.

    Thursday, February 16, 2006 11:45 PM
  •  Richard_Wolf wrote:

    Setting the tag property, or setting a form level variable is basically the same thing:  You save off the selection in the lost focus, clear the selection, then restore it in the got focus.  Any later code that needs to know what was selected must also reset the selection to get the information.  This seems kind of silly to me when simply supporting a ".HideSelection" property in the underlying control would be far simpler.  It should be as simple as "if I'm not the active control then don't do this highlight code."

    This process may be okay for an un-bound grid, but I don't think I'd want to try it on a databound grid with several thousand records.  Currently I'm just living with the highlight always being displayed =/.

    Yes, using the tag has a similar effect, but I think it's neater than using a form level variable/object.

    You are right about 'thousands of records': not sure how it would perform. However you have to remember one thing: even if you aren't doing it (the highlight/unhighlight) yourself, it's done in the control, it doesn't necessarily mean it's going to be a magnitude faster.

    Even so, your point is well taken - why isn't there a .HideSelection property?

    Friday, February 17, 2006 2:50 PM
  • I may be missing something here but what is wrong with the following

    When the control loses focus

    datagridview1.DefaultCellStyle.SelectionBackColor = Color.White

    datagridview1.DefaultCellStyle.SelectionForeColor = Color.Black

    and when it regains it

    datagridview1.DefaultcellStyle.SelectionBackColor = Color.Blue

    datagridview1.DefaultCellStyle.SelectionForeColor = Color.White

     

     

    Thursday, February 23, 2006 11:38 AM
  • Because that will just change the selection color, making the row appear to be un-selected.   Any special highlight colors you may have applied to the cells will not be visible.
    Thursday, February 23, 2006 3:58 PM
  • Like I said - I thought I must be missing something.

    What about this - it's a bit of a hack but not as messy as having to save stuff in form level variables.

    Add another column to your grid at one edge and make it as narrow as you can.  Make the background colour of the cells in this column the same colour as the cell in the adjacent row.

    When the grid loses focus change the selection mode to CellSelect and select the tiny cell at the end of the row.  Then change the selection highlight to the colour of the adjacent cell.

    Then any colours you have added will reappear when the control loses focus.

    When it regains focus set the selection mode back to FullRowSelect with the appropriate colour.

    In code mine looks a bit like the following:

    Private Sub DG1_GotFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles DG1.GotFocus

         bDG1Focussed = True

         DG1.DefaultCellStyle.SelectionBackColor = Color.Blue

         DG1.DefaultCellStyle.SelectionForeColor = Color.White

         DG1.SelectionMode = DataGridViewSelectionMode.FullRowSelect

    End Sub

    Private Sub DG1_LostFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles DG1.LostFocus

          DG1.DefaultCellStyle.SelectionBackColor = Color.White

         DG1.DefaultCellStyle.SelectionForeColor = Color.Black

         DG1.SelectionMode = DataGridViewSelectionMode.CellSelect

         DG1.CurrentCell = DG1(3, DG1.CurrentCell.RowIndex)

    End Sub

    I've tried it and visually it works well with the extra column being virtually invisible

     

    Dave

    Thursday, February 23, 2006 5:51 PM
  • That's a execellent solution, Dave, bit of a hassle but workable.  I'd recommend using System.Drawing.SystemColors.Hightlight/.HighlightText in lieu of "Color.Blue/.White" if themes are enabled.

    I haven't tested it, but does changing the selection mode to cell alter the .SelectedRows collection or will it sill maintain the last selected row?

    Thursday, February 23, 2006 9:01 PM
  • The row index of the grid is maintained when you change the selection mode so hopefully any code you have for extracting data from the grid will still work.

     

    Dave

    Friday, February 24, 2006 10:35 AM
  • At least it worked for me, although my problem was a bit different

    Thanks!

    Friday, May 12, 2006 3:16 PM
  • Hi,

    this isn't perfect, but it will work and keep the DGVs selection intact

    in the datagridview's leave event handler enter the following:

    Private Sub DataGridView1_Leave(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DataGridView1.Leave

    DataGridView1.DefaultCellStyle.SelectionBackColor = DataGridView1.DefaultCellStyle.BackColor

    DataGridView1.DefaultCellStyle.SelectionForeColor = DataGridView1.DefaultCellStyle.ForeColor

     

    End Sub

    And in the dgv enter event handler:

    Private Sub DataGridView1_Enter(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DataGridView1.Enter

    DataGridView1.DefaultCellStyle.SelectionForeColor = Color.White

    DataGridView1.DefaultCellStyle.SelectionBackColor = Color.Blue

     

    End Sub

    Hope it helps

    Mark

    Friday, May 19, 2006 1:37 PM
  • Richard,

    I know you asked about this a long time ago but I had the same question today. Here's what I did:

    First, I added a column at the beginning. I set AutoSizeMode to None. When I add data to the non-bound grid, I add "" in the first column:

    Dim rowInfo() As String = {"", "RealCol1text", "RealCol2text"}
    
    
    

    As a result, the highlight appears in the dummy cell in far left column which is just a thin sliver. This blue vertical line shows which row is selected but does not obstruct the view of the other cells. FYI, I'm using DataGridView in VS2010. While this may not have helped you in time for your previous project hopefully it will be useful in the future.


    rwb
    Wednesday, November 03, 2010 1:32 PM