Dzisiaj pokażę wam jak zrobić coś takiego jak na obrazku poniżej. Czyli jak dodać do naszego DatagridView Progressbar.
Każdemu zainteresowanemu systemami ERP takie rozwiązanie nie jest obce. Zaczynamy od nowego projektu i przenosimy na niego 2x DatagridView:
Po tej operacji nasza forma wygląda tak jak na zdjęciu:
Teraz dodamy sobie klasę. Aby to zrobić przechodzimy do Projekt>>Dodaj formularz systemu Windows…..
Znajdujemy Klasę i nazywamy ją jak chcemy (ja nazwałem ją „Paseknaladowania.vb”)
Po utworzeniu klasy powinna ona pojawić się po prawej stronie w „Eksploratorze rozwiązań”:
Otwieramy naszą klasę i wypełniamy ją kodem:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 |
Imports System Imports System.Drawing Imports System.Windows.Forms Public Class DataGridViewProgressBarColumn Inherits DataGridViewTextBoxColumn 'Konstruktor Public Sub New() Me.CellTemplate = New DataGridViewProgressBarCell() End Sub 'Szablon komórek, ustawienia Public Overrides Property CellTemplate() As DataGridViewCell Get Return MyBase.CellTemplate End Get Set(ByVal value As DataGridViewCell) If Not TypeOf value Is DataGridViewProgressBarCell Then Throw New InvalidCastException("DataGridViewProgressBarCell") End If MyBase.CellTemplate = value End Set End Property ''Wartość maksymalna Public Property Maximum() As Integer Get Return CType(Me.CellTemplate, DataGridViewProgressBarCell).Maximum End Get Set(ByVal value As Integer) If Me.Maximum = value Then Return End If CType(Me.CellTemplate, DataGridViewProgressBarCell).Maximum = value If Me.DataGridView Is Nothing Then Return End If Dim rowCount As Integer = Me.DataGridView.RowCount Dim i As Integer For i = 0 To rowCount - 1 Dim r As DataGridViewRow = Me.DataGridView.Rows.SharedRow(i) CType(r.Cells(Me.Index), DataGridViewProgressBarCell).Maximum = _ value Next i End Set End Property ''Wartość minimalna Public Property Mimimum() As Integer Get Return CType(Me.CellTemplate, DataGridViewProgressBarCell).Mimimum End Get Set(ByVal value As Integer) If Me.Mimimum = value Then Return End If CType(Me.CellTemplate, DataGridViewProgressBarCell).Mimimum = value If Me.DataGridView Is Nothing Then Return End If Dim rowCount As Integer = Me.DataGridView.RowCount Dim i As Integer For i = 0 To rowCount - 1 Dim r As DataGridViewRow = Me.DataGridView.Rows.SharedRow(i) CType(r.Cells(Me.Index), DataGridViewProgressBarCell).Mimimum = _ value Next i End Set End Property End Class 'Wyświetlanie ProgressBar w Datagridview Public Class DataGridViewProgressBarCell Inherits DataGridViewTextBoxCell 'Konstruktor Public Sub New() Me.maximumValue = 100 Me.mimimumValue = 0 End Sub Private maximumValue As Integer Public Property Maximum() As Integer Get Return Me.maximumValue End Get Set(ByVal value As Integer) Me.maximumValue = value End Set End Property Private mimimumValue As Integer Public Property Mimimum() As Integer Get Return Me.mimimumValue End Get Set(ByVal value As Integer) Me.mimimumValue = value End Set End Property 'Określa typ danych w komurkach 'Użyto wartości całkowitych Public Overrides ReadOnly Property ValueType() As Type Get Return GetType(Integer) End Get End Property 'Określa wartość domyślną nowego rekordu, zmiana tego parametru powoduje 'automatyczne wstawianiewartości w nowe komurki Public Overrides ReadOnly Property DefaultNewRowValue() As Object Get Return 0 End Get End Property Public Overrides Function Clone() As Object Dim cell As DataGridViewProgressBarCell = _ CType(MyBase.Clone(), DataGridViewProgressBarCell) cell.Maximum = Me.Maximum cell.Mimimum = Me.Mimimum Return cell End Function Protected Overrides Sub Paint(ByVal graphics As Graphics, _ ByVal clipBounds As Rectangle, _ ByVal cellBounds As Rectangle, _ ByVal rowIndex As Integer, _ ByVal cellState 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) 'Ustala wartość Dim intValue As Integer = 0 If TypeOf value Is Integer Then intValue = CInt(value) End If If intValue < Me.mimimumValue Then intValue = Me.mimimumValue End If If intValue > Me.maximumValue Then intValue = Me.maximumValue End If 'Oblicza procent Dim rate As Double = CDbl(intValue - Me.mimimumValue) / (Me.maximumValue - Me.mimimumValue) 'Rysuję linię granicy komórki (ramki) If (paintParts And DataGridViewPaintParts.Border) = DataGridViewPaintParts.Border Then Me.PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle) End If ' zasięg wewnątrz linii granicznej Dim borderRect As Rectangle = Me.BorderWidths(advancedBorderStyle) Dim paintRect As New Rectangle(cellBounds.Left + borderRect.Left, cellBounds.Top + borderRect.Top, cellBounds.Width - borderRect.Right, cellBounds.Height - borderRect.Bottom) Dim isSelected As Boolean = ((cellState And DataGridViewElementStates.Selected) = DataGridViewElementStates.Selected) Dim bkColor As Color If isSelected AndAlso (paintParts And DataGridViewPaintParts.SelectionBackground) = DataGridViewPaintParts.SelectionBackground Then bkColor = cellStyle.SelectionBackColor Else bkColor = cellStyle.BackColor End If 'Rysuje tło If (paintParts And DataGridViewPaintParts.Background) = DataGridViewPaintParts.Background Then Dim backBrush As New SolidBrush(bkColor) Try graphics.FillRectangle(backBrush, paintRect) Finally backBrush.Dispose() End Try End If paintRect.Offset(cellStyle.Padding.Right, cellStyle.Padding.Top) paintRect.Width -= cellStyle.Padding.Horizontal paintRect.Height -= cellStyle.Padding.Vertical 'Rysowanie progressBar If (paintParts And DataGridViewPaintParts.ContentForeground) = _ DataGridViewPaintParts.ContentForeground Then If ProgressBarRenderer.IsSupported Then 'styl rysowania 'rysowanie ramki 'Jeśli usuniemy tę opcje nasz progressbar będzie wyglądał nago :P ProgressBarRenderer.DrawHorizontalBar(graphics, paintRect) 'rysowanie paska Dim barBounds As New Rectangle(paintRect.Left + 3, paintRect.Top + 3, paintRect.Width - 4, paintRect.Height - 6) barBounds.Width = CInt(Math.Round((barBounds.Width * rate))) ProgressBarRenderer.DrawHorizontalChunks(graphics, barBounds) 'zmiana koloru progress baru ''' graphics.FillRectangle(Brushes.Aqua, barBounds) Else 'Jeżeli coś pójdzie nie tak powyżej nasz progressbar zostanie namalowany kodem poniżej 'można przekopiować ten kod powyżej i zobaczyć jak to wygląda, mało ciekawie graphics.FillRectangle(Brushes.White, paintRect) graphics.DrawRectangle(Pens.Black, paintRect) Dim barBounds As New Rectangle(paintRect.Left + 1, _ paintRect.Top + 1, _ paintRect.Width - 1, _ paintRect.Height - 1) barBounds.Width = CInt(Math.Round((barBounds.Width * rate))) graphics.FillRectangle(Brushes.Blue, barBounds) End If End If 'zmiana ostrości ramek 'chodzi tutaj o podświetlenie kropkami po wybraniu komurki i ostrość krawędzi tego podświetlenia If Me.DataGridView.CurrentCellAddress.X = Me.ColumnIndex AndAlso Me.DataGridView.CurrentCellAddress.Y = Me.RowIndex AndAlso _ (paintParts And DataGridViewPaintParts.Focus) = DataGridViewPaintParts.Focus AndAlso Me.DataGridView.Focused Then Dim focusRect As Rectangle = paintRect focusRect.Inflate(-3, -3) ControlPaint.DrawFocusRectangle(graphics, focusRect) End If 'wyświetlanie tekstu If (paintParts And DataGridViewPaintParts.ContentForeground) = _ DataGridViewPaintParts.ContentForeground Then 'określanie tekstu który będzie wyświetlany Dim txt As String = String.Format("{0}%", Math.Round((rate * 100))) Dim flags As TextFormatFlags = _ TextFormatFlags.HorizontalCenter Or _ TextFormatFlags.VerticalCenter 'kolor tekstu Dim fColor As Color = cellStyle.ForeColor paintRect.Inflate(-2, -2) TextRenderer.DrawText( _ graphics, txt, cellStyle.Font, paintRect, fColor, flags) End If 'Wyświetlanie ikon błędu If (paintParts And DataGridViewPaintParts.ErrorIcon) = _ DataGridViewPaintParts.ErrorIcon AndAlso _ Me.DataGridView.ShowCellErrors AndAlso _ Not String.IsNullOrEmpty(errorText) Then Dim iconBounds As Rectangle = _ Me.GetErrorIconBounds(graphics, cellStyle, rowIndex) iconBounds.Offset(cellBounds.X, cellBounds.Y) Me.PaintErrorIcon(graphics, iconBounds, cellBounds, errorText) End If End Sub End Class |
Ważniejsze rzeczy opisałem w kodzie. Aby zmienić kolor z zielonego na wybrany przez siebie należy aktywować w kodzie opcje:
1 2 3 |
ProgressBarRenderer.DrawHorizontalChunks(graphics, barBounds) 'zmiana koloru progress baru ''' graphics.FillRectangle(Brushes.Aqua, barBounds) |
który jest w 199 linijce kodu. Należy wybrać kolor po słowie „Brushes.(nasz kolor)”. W skrypcie powyżej macie kolor Aqua po aktywowaniu skryptu progressbar będzie wyglądał tak:
Mamy gotową klasę, trzeba ją teraz wykorzystać. Pokażę wam dwa sposoby które można wykorzystać.
Pierwszy z nich to dodanie danych przy Form_Load. Wygląda to tak:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Dim pbColumn As New DataGridViewProgressBarColumn() DataGridView1.ColumnCount = 2 DataGridView1.Columns(0).Name = "pierwsza" DataGridView1.Columns(0).AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill DataGridView1.Columns(1).Name = "drugi" DataGridView1.Columns(1).AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill DataGridView1.Columns.Add(pbColumn) DataGridView1.Columns(2).AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill pbColumn.HeaderText = "test" DataGridView1.Rows.Add() DataGridView1.Rows(0).Cells(0).Value = "test" DataGridView1.Rows(0).Cells(1).Value = "test" DataGridView1.Rows(0).Cells(2).Value = 25 DataGridView1.Rows.Add() DataGridView1.Rows(1).Cells(0).Value = "test2" DataGridView1.Rows(1).Cells(1).Value = "test2" DataGridView1.Rows(1).Cells(2).Value = 60 DataGridView1.Rows.Add() DataGridView1.Rows(2).Cells(0).Value = "test3" DataGridView1.Rows(2).Cells(1).Value = "test3" DataGridView1.Rows(2).Cells(2).Value = 50 End Sub |
Po uruchomieniu programu efekt będzie taki:
Dobra a jak użyć tego skryptu gdy mamy bazę danych typu *.mdf albo bazę danych na serwerze msql, bardzo prosto. Na potrzeby tego tutoriala dodałem sobie zwykłą lokalną bazę danych którą następnie wypełniłem danymi jak na obrazku.
Następnie dodałem źródło danych:
Następnie dodałem te dane (przenosząc je) do DatagridView2. Po odpaleniu wygląda to tak:
Aby ostatnia kolumna wyświetlała ProgressBar należy w projektancie „Edytować kolumny”:
Znajdujemy po lewej stronie naszą kolumnę i zmieniamy jej „Column Type” i wybieramy „DatagridViewProgressBarColumn”
Po tej operacji mamy już wewnątrz DatagridView ProgressBar:
Tym sposobem mamy fajny i dosyć elastyczny ProgressBar wewnątrz DatagridView. Tak jak zawsze projekt do pobrania macie tutaj: prograss bar w datagridview