I have bounded DataGridView with 5000 rows of data in Form where dgv "fill" forms area.
When I scroll it with keyboard up or down selected row flickers much on solid computer.
Is here a way to get rid of that flickering?
Here is how my DataGridView is setup:
With DataGridView1
.AllowUserToAddRows = False
.AllowDrop = False
.AllowUserToOrderColumns = False
.AllowUserToResizeRows = False
.ColumnHeadersDefaultCellStyle.Font = fnt1
.SelectionMode = DataGridViewSelectionMode.FullRowSelect
.ScrollBars = ScrollBars.Vertical
.MultiSelect = False
.ReadOnly = True
.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft
.GridColor = Color.FromArgb(240, 240, 240)
.DefaultCellStyle.Font = fnt1
.BorderStyle = BorderStyle.None
.Dock = DockStyle.Fill
End With
You can get rid of the flickering by implementing double buffering for that form
me.SetStyle(
ControlStyles.AllPaintingInWmPaint OR _
ControlStyles.UserPaint OR _
ControlStyles.DoubleBuffer,true)
This should work
try this then
i really hope it helps
Related
Greetings to the community.
I am trying to modify a checkbox column of a DataGridView in VB.NET. I hope you can help me.
I am looking to go from this:
To this:
That is, even if I click or double click on the cell, the checkbox is not selected.
Part of the code where the columns are added to DataGridView (DvgNeumaticos):
If BtnVistaPorFacturar.Checked Then
For i As Integer = 0 To DgvNeumaticos.Columns.Count - 1
DgvNeumaticos.Columns(i).Visible = False
Next
DgvNeumaticos.Columns("ColChk").Visible = True
DgvNeumaticos.Columns("CodOS").Visible = True
DgvNeumaticos.Columns("Tipo").Visible = True
DgvNeumaticos.Columns("NroOrden").Visible = True
DgvNeumaticos.Columns("NroOrden").DisplayIndex = 0
DgvNeumaticos.Columns("FechaOS").Visible = True
DgvNeumaticos.Columns("F.Cierre").Visible = True
DgvNeumaticos.Columns("Observacion").Visible = True
DgvNeumaticos.Columns("CodNeumatico").Visible = True
DgvNeumaticos.Columns("Externo").Visible = True
DgvNeumaticos.Columns("CodTercero").Visible = True
DgvNeumaticos.Columns("CodProducto").Visible = True
DgvNeumaticos.Columns("Producto").Visible = True
DgvNeumaticos.Columns("Trabajo").Visible = True
DgvNeumaticos.Columns("NroDocRecepcion").Visible = True
DgvNeumaticos.Columns("FechaRecepcion").Visible = True
New Edit:
If BtnVistaPorFacturar.Checked Then
Dim chkCol As New DataGridViewCheckBoxColumn
chkCol.Name = "ColChk"
chkCol.HeaderText = "Chk"
DgvNeumaticos.Columns.Add(chkCol)
dt = WFOrdServicioNeumaticos.Instancia.fdu_NEUM_ORDSERV_VerOrdenesPorFacturar(.Cells("IDAgente").Value)
End If
Thanks for the replies.
not sure if there is an easier way to do this but I have a LOT of buttons on a form. Different ones are visible for different functions.
Is there a way to have something like this have an easier way to change their visibility without having each button coded to go False/True?
For simplicity sake, I created a quick app to handle the visibility but I want to hide the others when one set of buttons is visible. So if I select Row 1, it will make Visibility FALSE on Row 2 and 3.
Am I stuck with this or is there an easier way/more efficient way? THANKS IN ADVANCE!
Public Class Form1
Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
If ComboBox1.SelectedItem.ToString = "Button Row 1" Then
Button1.Visible = True
Button2.Visible = True
Button3.Visible = True
Button4.Visible = True
Button5.Visible = True
Button6.Visible = True
Button7.Visible = True
Button8.Visible = True
Button9.Visible = True
Button10.Visible = True
Button11.Visible = False
Button12.Visible = False
Button13.Visible = False
Button14.Visible = False
Button15.Visible = False
Button16.Visible = False
Button17.Visible = False
Button18.Visible = False
Button19.Visible = False
Button20.Visible = False
Button21.Visible = False
Button22.Visible = False
Button23.Visible = False
Button24.Visible = False
Button25.Visible = False
Button26.Visible = False
Button27.Visible = False
Button28.Visible = False
Button29.Visible = False
Button30.Visible = False
ElseIf ComboBox1.SelectedItem.ToString = "Button Row 2" Then
Button1.Visible = False
Button2.Visible = False
Button3.Visible = False
Button4.Visible = False
Button5.Visible = False
Button6.Visible = False
Button7.Visible = False
Button8.Visible = False
Button9.Visible = False
Button10.Visible = False
Button11.Visible = True
Button12.Visible = True
Button13.Visible = True
Button14.Visible = True
Button15.Visible = True
Button16.Visible = True
Button17.Visible = True
Button18.Visible = True
Button19.Visible = True
Button20.Visible = True
Button21.Visible = False
Button22.Visible = False
Button23.Visible = False
Button24.Visible = False
Button25.Visible = False
Button26.Visible = False
Button27.Visible = False
Button28.Visible = False
Button29.Visible = False
Button30.Visible = False
ElseIf ComboBox1.SelectedItem.ToString = "Button Row 3" Then
Button1.Visible = False
Button2.Visible = False
Button3.Visible = False
Button4.Visible = False
Button5.Visible = False
Button6.Visible = False
Button7.Visible = False
Button8.Visible = False
Button9.Visible = False
Button10.Visible = False
Button11.Visible = False
Button12.Visible = False
Button13.Visible = False
Button14.Visible = False
Button15.Visible = False
Button16.Visible = False
Button17.Visible = False
Button18.Visible = False
Button19.Visible = False
Button20.Visible = False
Button21.Visible = True
Button22.Visible = True
Button23.Visible = True
Button24.Visible = True
Button25.Visible = True
Button26.Visible = True
Button27.Visible = True
Button28.Visible = True
Button29.Visible = True
Button30.Visible = True
End If
End Sub
End Class
Set the tag property of the buttons. You can do it in the properties window. I just show it in code to illustrate the point
Button1.Tag = "Button Row 1"
Then you can do
Dim selectedRow = ComboBox1.SelectedItem.ToString()
For Each c As Control In Controls
If (TypeOf c Is Button) Then
c.Visible = selectedRow.Equals(c.Tag)
End If
Next
Note that this automatically shows the buttons of the selected row and hides the others.
If this affects too many buttons, you can also check if the Tag is not Nothing instead of testing if it is a button.
You could use a for loop and keep track of which textbox is in which row, could put the row in the name, tag, use a custom property, etc.
You could put each row in a groupbox and just change the visibility of the group.
You could make a list of Buttons for each row, add the buttons, and loop through those lists.
Winforms support data binding.
' In form constructor
public Sub New()
InitializeComponent()
cmbEnableButtons.DataSource = New List(Of string) From
{
"Nothing",
"Button Row 1",
"Button row 2"
}
button1.Tag = "Button Row 1"
button2.Tag = "Button Row 1"
button3.Tag = "Button Row 2"
button4.Tag = "Button Row 2"
button1.DataBindings.Add(CreateBindingForVisible())
button2.DataBindings.Add(CreateBindingForVisible())
button3.DataBindings.Add(CreateBindingForVisible())
button4.DataBindings.Add(CreateBindingForVisible())
}
Private Function CreateBindingForVisible() As Binding
Dim buttonBinding =
New Binding("Visible",
cmbEnableButtons,
"SelectedValue",
true,
DataSourceUpdateMode.OnPropertyChanged)
' Every time selected value of combobox changed
' this event handler convert string to "visible" boolean
AddHandler buttonBinding.Format, AddressOf ButtonBinding_Format
return buttonBinding;
End Sub
Private Sub ButtonBinding_Format(object sender, ConvertEventArgs e)
Dim binding = DirectCast(sender, Binding)
Dim button = DirectCast(binding.Control, Button)
e.Value = Equals(button.Tag, e.Value)
End Sub
With data binding you can configure every button separately from each other, while having common logic in one place.
On my form i got datagridview which is populating by some data. There is also a combobx on this form and when selection change has happend then based on selected value - datagridview datasource is set to be nothing and then filled up again. Everything was working well until i decided to add additional datagridview image column which i placed on the end of grid and to show images based on text from some previous column text data. Unfortunetly i have problem with displaying images itself (red marks) and biggest problem is when i change combobox selection my additional datagrid image column is moving 1 position to left everytime combo is changed. I've spent whole day looking for issue but can't find any answer on that. I thought maybe that's because grid datasource is not being cleaned (nothing) but it is. Can you please help me out what could be a problem here? Below find my code and screenshoots of problem. Hope you help me to fix it as i am really stackoverflowed.
My Form Load event - that's where i load combobox:
Private Sub FrmTransportView_Load(sender As Object, e As EventArgs) Handles MyBase.Load
RemoveHandler CboProjects.SelectedIndexChanged, AddressOf CboProjects_SelectedIndexChanged
Try
mydb.OpenConn()
If mydb.conn.State = ConnectionState.Open Then
Form.InitCombo(CboProjects, "SELECT * from tbProjekt", mydb.conn, "Nazwa", "Id")
mydb.CloseConn()
'ChangeControlsLanguage()
Trans = New Transport
Trans.ProjectId = CboProjects.SelectedValue
RefreshGridAfterProjectIdChanged()
AddHandler CboProjects.SelectedIndexChanged, AddressOf CboProjects_SelectedIndexChanged
End Try
End Sub
PopulateGrid method:
Public Sub PopulateGrid()
Try
If IsNothing(Trans.ListByProjectId_checkifanyrows()) Then
Me.BeginInvoke(New MethodInvoker(AddressOf Me.Close))
Else
Else
dgvTransport.DataSource = Nothing 'Clean datagrid before new data
dgvTransport.Refresh()
dgvTransport.DataSource = Trans.ListByProjectId()
AlignGrid()
PlaceImages()
End If
End Try
End Sub
Align method - placed within PopulateGrid method as you see when dgvTransport as set to nohing and then its detasource set to new data: Trans.ListByProjectId() now i am aligning it - hiding some columns etc... As you can see also i am adding this new image column... :
Private Sub AlignGrid()
Try
dgvTransport.Columns(0).Visible = False 'Project id
dgvTransport.Columns(1).Visible = False 'Id
dgvTransport.Columns(2).Visible = True 'Lp
dgvTransport.Columns(3).Visible = True 'Status
dgvTransport.Columns(4).Visible = True 'Dataprzyjazdu
dgvTransport.Columns(5).Visible = True 'DataRozpoczeciaZaladunku
dgvTransport.Columns(6).Visible = True 'DataOdjazdu
dgvTransport.Columns(7).Visible = True 'TypTransportu dgvTransport.Columns(8).Visible = False 'TypKontenera (reprezentacja liczbowa z tabeli tbTransport)
dgvTransport.Columns(9).Visible = True 'NumerKontenera
dgvTransport.Columns(10).Visible = True 'NumerCiezarowki
dgvTransport.Columns(11).Visible = True 'Plomba
dgvTransport.Columns(12).Visible = False 'Kierowca
dgvTransport.Columns(13).Visible = False 'Opis
dgvTransport.Columns(14).Visible = False 'Nazwa (nazwa projektu)
dgvTransport.Columns(15).Visible = True 'TypKontenera (reprezentacja za pomoca nazwy ze zlaczenia INNER JOIN))
Dim img As DataGridViewImageColumn = New DataGridViewImageColumn()
img.HeaderText = "Status2"
img.Name = "Status2"
dgvTransport.Columns.Insert(16, img)
'potrzebny aby zadzialalo: DgvMach.ColumnHeadersDefaultCellStyle.BackColor = Color.Gold
dgvTransport.EnableHeadersVisualStyles = False
'headers look
With dgvTransport.ColumnHeadersDefaultCellStyle
'The way to do this is to set the EnableHeadersVisualStyles flag for the data grid view to False, and set the background colour via the ColumnHeadersDefaultCellStyle.BackColor property. For example, to set the background colour to blue, use the following (or set in the designer if you prefer):
'If you do not set the EnableHeadersVisualStyles flag to False, then the changes you make to the style of the header will not take effect, as the grid will use the style from the current users default theme. The MSDN documentation for this property is here.
.BackColor = Color.White
.ForeColor = Color.Black
.Font = New Font("Ariel", 10, FontStyle.Regular)
.Alignment = DataGridViewContentAlignment.MiddleCenter
End With
dgvTransport.AllowUserToAddRows = False
dgvTransport.[ReadOnly] = True
dgvTransport.MultiSelect = False
dgvTransport.SelectionMode = DataGridViewSelectionMode.FullRowSelect 'zaznacza caly wiersz po kliknieciu
dgvTransport.AutoSizeColumnsMode = DataGridViewAutoSizeColumnMode.Fill 'WAZNE!!!: RESIZUJE CALY CONTENT GRIDA NIE ZOSSTAWIAJAC CIEMNEGO TLA !!!
dgvTransport.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells
With dgvTransport.DefaultCellStyle
.BackColor = Color.White
.ForeColor = Color.Black
.Font = New Font("Ariel", 9, FontStyle.Regular)
.Alignment = DataGridViewContentAlignment.MiddleCenter
End With
'This will disable row autosizing and manual row resizing. To set the row height you can use the Height and MinimumHeight properties of the RowTemplate.
dgvTransport.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None
dgvTransport.AllowUserToResizeRows = False
End Sub
FrmTransportView_Shown event:
Private Sub FrmTransportView_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
AddHandler dgvTransport.SelectionChanged, AddressOf dgvTransport_SelectionChanged
End Sub
RefreshGridAfterProjectIdChanged
Public Sub RefreshGridAfterProjectIdChanged()
Trans.ProjectId = CboProjects.SelectedValue
PopulateGrid()
End Sub
CboProjects_SelectedIndexChanged
Private Sub CboProjects_SelectedIndexChanged(sender As Object, e As EventArgs) Handles CboProjects.SelectedIndexChanged
RefreshGridAfterProjectIdChanged()
End Sub
PlaceImages
Private Sub PlaceImages()
For i As Integer = 0 To dgvTransport.Rows.Count - 1
Dim sHeader As String = dgvTransport.Columns(16).Name
If sHeader = "Status2" Then
Dim LINK = dgvTransport.Rows(i).Cells(8).Value
If LINK.ToString.Contains("1") Then
Dim Img As New DataGridViewImageCell
Img.Value = My.Resources._1
dgvTransport.Rows(i).Cells(16).Value = Img.Value
End If
If LINK.ToString.Contains("2") Then
Dim Img As New DataGridViewImageCell
Img.Value = My.Resources._2
dgvTransport.Rows(i).Cells(16).Value = Img.Value
End If
If LINK.ToString.Contains("3") Then
Dim Img As New DataGridViewImageCell
Img.Value = My.Resources._3
dgvTransport.Rows(i).Cells(16).Value = Img.Value
End If
End If
Next
End Sub
That's how it looks for first form load: (strange thing is column index of image column (Status2) is 0 - should be 16 as i placed index for that column to 16 in Align method.. As you see also not images are showing up...
Now when i am going to change selection in combobox:
of course as you can note from code this method handler is called: CboProjects_SelectedIndexChanged
so then again grid datasource will be set to Nothing, populate again, then align gird..
and that's what is shown after: (see indexes - also some image show up and column "Status2" was moved to left..)
3rd combobox change etc...
Hope to find someone here to help me out as i really have no idea how to fix that. Hope everything is clear.
Sorry this is coming a little late. Just a suggestion - I didn't experiment with it. Try to insert the DataGridImageColumn first before editing the visibility of the other columns.
Not too related, but in your AlignGrid sub, the static properties like ".BackColor" can be set on design just to reduce code.
Let us know your observations.
Thanks
I set up some datatables via the Visual Studio table/columns collection editor. Sadly, it appears MS didn't include any way to re-order the data columns in the collection editor once you've done (no up/down facility). Thus, I'm having to programmatically re-order my columns (as out of order in the collection).
Done a lot of reading on this and for the life of me, can't locate the source of the problem. Basically, despite the code below, the datacolumns still show out-of-order on the datagridview. Code (abridged):
Private Sub LoadTextStylesDGV()
With _TextStylesDGV
.DefaultCellStyle.Padding = New Padding(0, 5, 0, 5)
.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells
.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells
.AllowUserToAddRows = False
.AllowUserToDeleteRows = False
.AllowUserToResizeColumns = True
.Columns.Add(New DataGridViewComboBoxColumn With {.DataPropertyName = "TextAlign", .Visible = True,
.Name = "TextAlign",
.HeaderText = "TextAlign",
.DataSource = MarqueeEditor._EnumDDContentAlign,
.FlatStyle = FlatStyle.Flat,
.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells})
' And other column setups similar to above
' ....
.DataSource = Global.CPWBAdmin.MarqueeEditor.MarqueeData.Tables("TextStyles")
.MultiSelect = False
.AllowUserToDeleteRows = False
With .Columns("ID")
.ReadOnly = True
.DefaultCellStyle.BackColor = Color.LightGray
.Visible = False
.DisplayIndex = 0
.Frozen = True
End With
With .Columns("Name")
.DisplayIndex = 1
.Frozen = True
.DefaultCellStyle.BackColor = Color.Linen
End With
.Columns("RandomStyle?").DisplayIndex = 2
With .Columns("Font")
.ReadOnly = True
.DefaultCellStyle.BackColor = Color.LightBlue
.AutoSizeMode = DataGridViewAutoSizeColumnMode.None
.DisplayIndex = 3
End With
'.... other column display index settings
.Columns("Stroke3LineJoin").DisplayIndex = 49
.Columns("Stroke3Wrap").DisplayIndex = 50
.Columns("TextAutoFit").DisplayIndex = 51
'Sort:
.Sort(_TextStylesDGV.Columns("Name"), System.ComponentModel.ListSortDirection.Ascending)
End With
End Sub
I'm wondering whether the DGV columns are getting re-ordered elsewhere in the code. Of course - no way to check this with step-by-step debugging as happens before form show. Have trawled through the code but can't see anything obvious. Does anyone have any ideas as this one is killing me! If only MS had allowed column collection re-ordering. :(
Oooops. Didn't search hard enough! Finally found the solution:
dgvReservedStalls.AutoGenerateColumns = True
dgvReservedStalls.DataSource = clsReservedStalls.LoadDataTable()
dgvReservedStalls.AutoGenerateColumns = False
auto generates the columns from the DT, then frees it for re-ordering the columns. A little obscure, MS... :)
From here
I'm trying to disable the border around a cell when selected! (The black rectangle, not the blue background).
Is that possible?
this is my grid initialization code (maybe will help):
With DBGrid
.RowHeadersVisible = False
.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.DisableResizing
.RowTemplate.Height = internal_RowHeight
' Set property values appropriate for read-only display and
' limited interactivity.
.AllowUserToAddRows = False
.AllowUserToDeleteRows = False
.AllowUserToOrderColumns = False
.ReadOnly = True
.SelectionMode = DataGridViewSelectionMode.FullRowSelect
.AllowUserToResizeColumns = False
.AllowUserToResizeRows = False
.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None
' Set the row height
.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.EnableResizing
.ColumnHeadersHeight = internal_RowHeight
.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing
' Set the selection background color for all the cells.
.DefaultCellStyle.BackColor = internal_BackColor
.DefaultCellStyle.ForeColor = internal_ForeColor
.DefaultCellStyle.SelectionBackColor = internal_BackColorSel
.DefaultCellStyle.SelectionForeColor = internal_ForeColorSel
' Set RowHeadersDefaultCellStyle.SelectionBackColor so that its default
' value won't override DataGridView.DefaultCellStyle.SelectionBackColor.
.RowHeadersDefaultCellStyle.SelectionBackColor = Color.Empty
.RowsDefaultCellStyle.BackColor = Color.Empty
' Set the row and column header styles.
.ColumnHeadersDefaultCellStyle.ForeColor = Color.White
.ColumnHeadersDefaultCellStyle.BackColor = Color.Black
End With
Since you want to disable the active cell, I would assume you only intend to use the grid as a way to select a row and not edit the contents.
In that case, use the following settings:
DataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect
DataGridView1.ReadOnly = True