Discussion:
Datagridview, Checkbox nur ein einigen Zeilen
(zu alt für eine Antwort)
Christina Heß
2009-07-09 14:43:34 UTC
Permalink
Hallo,

ich habe ein Datagridview und hole Daten mit einer Abfrage aus einer
Tabelle. Dann füge ich mit

Dim cb as new DatagridviewCheckBoxColumn
cb.Name = "Erfassung"
gri.columns.add(cb)

eine Spalte mit Checkboxen hinzu. das funktioniert prima.

Nur nun sollen die Checkboxen nur angezeigt werden, wenn in einer anderen
Spalte ein bestimmter Wert steht.
Die anderen Zeilen (die dann ohne Checkbox ) sollen zur Eingabe gesperrt
werden.

Hat jemand eine Idee, wie man das machen kann?

Vielen Dank schonmal
Christina
Peter Götz
2009-07-09 16:08:36 UTC
Permalink
Hallo Christina,
Post by Christina Heß
ich habe ein Datagridview und hole Daten mit einer
Abfrage aus einer > Tabelle. Dann füge ich mit
Dim cb as new DatagridviewCheckBoxColumn
cb.Name = "Erfassung"
gri.columns.add(cb)
eine Spalte mit Checkboxen hinzu. das funktioniert prima.
Nur nun sollen die Checkboxen nur angezeigt werden, wenn
in einer anderen Spalte ein bestimmter Wert steht.
Bis hierher kann ich noch folgen.
Post by Christina Heß
Die anderen Zeilen (die dann ohne Checkbox ) sollen zur
Eingabe gesperrt werden.
Das heisst, dass solche Zeilen niemals verändert werden
können?

Sollen neue Zeilen hinzugefügt werden können?
Post by Christina Heß
Hat jemand eine Idee, wie man das machen kann?
Noch nicht so ganz.

Gruß aus St.Georgen
Peter Götz
www.gssg.de (mit VB-Tipps u. Beispielprogrammen)
Christina Heß
2009-07-09 18:00:27 UTC
Permalink
Hallo Peter,


ich möchte, das nur für Zeilen, in denen bei Status Aktiv steht, die
Checkbox angezeigt und bearbeitet werden kann, für die anderen Zeilen soll
die Spalte nicht bearbeitet werden, deshalb ist dort keine Checkbox nötig.

Neue Zeilen sollen nicht angefügt werden.

Das Beispiel von andern Post schaue ich mir nachher mal an, ob das
weiterhilft. Danke schonmal

Grüße
Christina
Post by Peter Götz
Hallo Christina,
Post by Christina Heß
ich habe ein Datagridview und hole Daten mit einer
Abfrage aus einer > Tabelle. Dann füge ich mit
Dim cb as new DatagridviewCheckBoxColumn
cb.Name = "Erfassung"
gri.columns.add(cb)
eine Spalte mit Checkboxen hinzu. das funktioniert prima.
Nur nun sollen die Checkboxen nur angezeigt werden, wenn
in einer anderen Spalte ein bestimmter Wert steht.
Bis hierher kann ich noch folgen.
Post by Christina Heß
Die anderen Zeilen (die dann ohne Checkbox ) sollen zur
Eingabe gesperrt werden.
Das heisst, dass solche Zeilen niemals verändert werden
können?
Sollen neue Zeilen hinzugefügt werden können?
Post by Christina Heß
Hat jemand eine Idee, wie man das machen kann?
Noch nicht so ganz.
Gruß aus St.Georgen
Peter Götz
www.gssg.de (mit VB-Tipps u. Beispielprogrammen)
Peter Götz
2009-07-09 18:12:40 UTC
Permalink
Hallo Chistina,
Post by Christina Heß
ich möchte, das nur für Zeilen, in denen bei Status
Aktiv steht, die Checkbox angezeigt und bearbeitet
werden kann, für die anderen Zeilen soll
die Spalte nicht bearbeitet werden, deshalb ist
dort keine Checkbox nötig.
Nach Deinem ersten Posting habe ich es so verstanden
dass die ganze Zeile ReadOnly gesetzt werden soll,
wenn der Inhalt einer Spalte x einen bestimmten Wert
hat. Im Beispiel aus meinem anderen Posting wäre
das eben ein Text in Spalte LText der mit "r" oder "R"
endet.
Wenn nur die Zelle mit der Checkbox gesperrt werden
soll, dann musst Du den Code eben leicht abändern
und statt DGV.Rows(x).ReadOnly eben nur
DGV.Rows(x).Cells(y).ReadOnly setzen.
Post by Christina Heß
Neue Zeilen sollen nicht angefügt werden.
Das vereinfacht den Code um einiges, da
bestimmte Abfragen (auf Nothing bzw. DBNull.Value)
bezügl. der neuen Zeile nicht mehr erforderlich sind.
Post by Christina Heß
Das Beispiel von andern Post schaue ich mir nachher
mal an, ob das weiterhilft.
Ich denke, vom Prinzip her sollte es für Dein
Anliegen passen. Statt die Checkboxen unsichtbar zu
machen, was nur sehr schwer und sehr viel Aufwand
möglich wäre, ändere ich einfach die ThreeState-
Eigenschaft der jeweiligen CheckBoxColumn und
setze sie auf CheckState.Indeterminate als Kennzeichen
dafür, dass diese Zeile (resp. Zelle) gesperrt ist.
Post by Christina Heß
Danke schonmal
Bitteschön.

Gruß aus St.Georgen
Peter Götz
www.gssg.de (mit VB-Tipps u. Beispielprogrammen)
Christina Heß
2009-07-10 22:32:18 UTC
Permalink
Hallo Peter,

ich habe mir Dein Bespiel angeschaut, das Verhalten der Checkboxen ist wie
gewünscht.
Und nun dachte ich, das ich die für mich relevanten Teile von Deinem Code
verwende und habe bei mir folgendes eingebaut:

If griFocusProdukte.Rows.Count > 0 Then
For i As Integer = 1 To griFocusProdukte.RowCount - 1
If griFocusProdukte.Rows(i).Cells("Status").Value <> "avtiv"
Then

Dim Ccbox As DataGridViewCheckBoxCell = _
DirectCast(griFocusProdukte.Rows(i).Cells("Einsatz
OK"), _
DataGridViewCheckBoxCell)

Ccbox.ThreeState = True
Ccbox.Value = CheckState.Indeterminate
Ccbox.ReadOnly = True

End If
Next
End If

Die Abfrage nach dem Zellinhalt für Status funktioniert und die Zeilen
werden auch abgearbeitet, aber am Ende sind alle Checkboxen so wie vorher
aus und können bearbeitet werden.

Was habe ich übersehen?

Viele Grüße
Christina
Peter Götz
2009-07-11 16:20:49 UTC
Permalink
Hallo Christina,
Post by Christina Heß
ich habe mir Dein Bespiel angeschaut, das Verhalten
der Checkboxen ist wie gewünscht.
Und nun dachte ich, das ich die für mich relevanten
Teile von Deinem Code verwende und habe bei mir
If griFocusProdukte.Rows.Count > 0 Then
For i As Integer = 1 To griFocusProdukte.RowCount - 1
If griFocusProdukte.Rows(i).Cells("Status").Value <> "avtiv" Then
Soll Valute tatsächlich auf <> "avtiv" und nicht eher
auf "aktiv" abgefragt werden?

griFocusProdukte.RowCount - 1 darf aber nur sein, wenn
das Grid keine neue Zeile zulässt, also DGV.AllowNew = false
ist.
Post by Christina Heß
Dim Ccbox As DataGridViewCheckBoxCell = _
DirectCast(griFocusProdukte.Rows(i).Cells("Einsatz OK"), _
DataGridViewCheckBoxCell)
Ccbox.ThreeState = True
Ccbox.Value = CheckState.Indeterminate
Ccbox.ReadOnly = True
E nd If
Next
End If
Die Abfrage nach dem Zellinhalt für Status funktioniert
und die Zeilen werden auch abgearbeitet, aber am Ende
sind alle Checkboxen so wie vorher aus und können
bearbeitet werden.
Wenn der Code, insbesondere Ccbox.ReadOnly = True
abgearbeitet wird und die Checkboxen später doch
bearbeitet werden können, gibt es in Deinem Code
nicht irgendetwas hier nicht gezeigtes, was Ccbox.ReadOnly
wieder auf False setzt.
Post by Christina Heß
Was habe ich übersehen?
Irgendwelchen Code, der Dein obiges ReadOnly = True
wieder aufhebt.
Man sollte auch noch wissen, wie und von wem
Dein Grid mit den Daten versorgt wird (Code)?

Gruß aus St.Georgen
Peter Götz
www.gssg.de (mit VB-Tipps u. Beispielprogrammen)
Christina Hess
2009-07-13 11:46:56 UTC
Permalink
Hallo Peter,

hier mal der Code

Dim CSQL As String

CSQL = "Select * from Artikel where Land = 'D'"



Dim dt As DataTable = db.GetDataTable(CSQL)

griFocusProdukte.DataSource = dt



Dim cb As New DataGridViewCheckBoxColumn

cb.Name = "Einsatz POS"

griFocusProdukte.Columns.Add(cb)

Dim cx As New DataGridViewTextBoxColumn

cx.Name = "Anzahl Regal"

griFocusProdukte.Columns.Add(cx)

cx = New DataGridViewTextBoxColumn

cx.Name = "Anzahl ZweitPlatzierung"

griFocusProdukte.Columns.Add(cx)



griFocusProdukte.AlternatingRowsDefaultCellStyle.BackColor = Color.LightCyan

If griFocusProdukte.Rows.Count > 0 Then

For i As Integer = 1 To griFocusProdukte.RowCount - 1

If griFocusProdukte.Rows(i).Cells("Status").Value <> "aktiv" Then

' **** Das macht hier schon sin, da es verschiedene Stati
geben kann und alle die unterschiedlich sind, sollen deaktiviert werden.
*****'

Dim Ccbox As DataGridViewCheckBoxCell = _

DirectCast(griFocusProdukte.Rows(i).Cells("Einsatz OK"), _

DataGridViewCheckBoxCell)

Ccbox.ThreeState = True

Ccbox.Value = CheckState.Indeterminate

Ccbox.ReadOnly = True

End If

Next

End If





griFocusProdukte.Columns("P_ProduktID").Visible = False

griFocusProdukte.Columns("P_PlattformID").Visible = False

'nicht editierbar:

griFocusProdukte.Columns("P_ProduktID").ReadOnly = True

griFocusProdukte.Columns("SKU").ReadOnly = True

griFocusProdukte.Columns("P_PlattformID").ReadOnly = True

griFocusProdukte.Columns("Titel").ReadOnly = True

griFocusProdukte.Columns("Plattform").ReadOnly = True

griFocusProdukte.Columns("Status").ReadOnly = True

resizeGrid(griFocusProdukte, False, True)





Nach diversen Tests habe ich nun herausgefunden, das der Code fuktioniert,
wenn ich ihn ausführe, wenn ich hinter ein Click-Event eines Buttons packe.
Im Load / Shown / activate Event der Form funktioniert das nicht.

Any Ideas ?



Viele Grüße

Christina
Christina Hess
2009-07-13 12:08:57 UTC
Permalink
In meiner Testform funktioniert es auch im Load- Event - bin nun mehr als
ratlos, warum es nicht da funktioniert, wo es soll.

Klar ist die Form komplexer, aber nach dem Füllen diese Grids passiert
eigentlich nichts mehr im Code.

Ich habe auch schon ein neues Grid mit neuem Namen eingefügt und das alte
gelöscht um ganz sicher zu sein, das nicht doch irgendwo noch ein Zugriff
erfolgt, aber das Problem bleibt.

Viele Grüße
Christina
Post by Christina Heß
Hallo Peter,
hier mal der Code
Dim CSQL As String
CSQL = "Select * from Artikel where Land = 'D'"
Dim dt As DataTable = db.GetDataTable(CSQL)
griFocusProdukte.DataSource = dt
Dim cb As New DataGridViewCheckBoxColumn
cb.Name = "Einsatz POS"
griFocusProdukte.Columns.Add(cb)
Dim cx As New DataGridViewTextBoxColumn
cx.Name = "Anzahl Regal"
griFocusProdukte.Columns.Add(cx)
cx = New DataGridViewTextBoxColumn
cx.Name = "Anzahl ZweitPlatzierung"
griFocusProdukte.Columns.Add(cx)
griFocusProdukte.AlternatingRowsDefaultCellStyle.BackColor =
Color.LightCyan
If griFocusProdukte.Rows.Count > 0 Then
For i As Integer = 1 To griFocusProdukte.RowCount - 1
If griFocusProdukte.Rows(i).Cells("Status").Value <> "aktiv" Then
' **** Das macht hier schon sin, da es verschiedene Stati
geben kann und alle die unterschiedlich sind, sollen deaktiviert werden.
*****'
Dim Ccbox As DataGridViewCheckBoxCell = _
DirectCast(griFocusProdukte.Rows(i).Cells("Einsatz OK"), _
DataGridViewCheckBoxCell)
Ccbox.ThreeState = True
Ccbox.Value = CheckState.Indeterminate
Ccbox.ReadOnly = True
End If
Next
End If
griFocusProdukte.Columns("P_ProduktID").Visible = False
griFocusProdukte.Columns("P_PlattformID").Visible = False
griFocusProdukte.Columns("P_ProduktID").ReadOnly = True
griFocusProdukte.Columns("SKU").ReadOnly = True
griFocusProdukte.Columns("P_PlattformID").ReadOnly = True
griFocusProdukte.Columns("Titel").ReadOnly = True
griFocusProdukte.Columns("Plattform").ReadOnly = True
griFocusProdukte.Columns("Status").ReadOnly = True
resizeGrid(griFocusProdukte, False, True)
Nach diversen Tests habe ich nun herausgefunden, das der Code fuktioniert,
wenn ich ihn ausführe, wenn ich hinter ein Click-Event eines Buttons
packe. Im Load / Shown / activate Event der Form funktioniert das nicht.
Any Ideas ?
Viele Grüße
Christina
Peter Götz
2009-07-13 14:09:02 UTC
Permalink
Hallo Christina,
Post by Christina Heß
Hallo Peter,
hier mal der Code
Dim CSQL As String
CSQL = "Select * from Artikel where Land = 'D'"
Dim dt As DataTable = db.GetDataTable(CSQL)
griFocusProdukte.DataSource = dt
Dim cb As New DataGridViewCheckBoxColumn
cb.Name = "Einsatz POS"
griFocusProdukte.Columns.Add(cb)
Dim cx As New DataGridViewTextBoxColumn
cx.Name = "Anzahl Regal"
griFocusProdukte.Columns.Add(cx)
cx = New DataGridViewTextBoxColumn
cx.Name = "Anzahl ZweitPlatzierung"
griFocusProdukte.Columns.Add(cx)
griFocusProdukte.AlternatingRowsDefaultCellStyle.BackColor =
Color.LightCyan
Post by Christina Heß
If griFocusProdukte.Rows.Count > 0 Then
For i As Integer = 1 To griFocusProdukte.RowCount - 1
If griFocusProdukte.Rows(i).Cells("Status").Value <> "aktiv" Then
' **** Das macht hier schon sin, da es verschiedene Stati
geben kann und alle die unterschiedlich sind, sollen deaktiviert werden.
*****'
Dim Ccbox As DataGridViewCheckBoxCell = _
DirectCast(griFocusProdukte.Rows(i).Cells("Einsatz OK"), _
DataGridViewCheckBoxCell)
Ccbox.ThreeState = True
Ccbox.Value = CheckState.Indeterminate
Ccbox.ReadOnly = True
End If
Next
End If
griFocusProdukte.Columns("P_ProduktID").Visible = False
griFocusProdukte.Columns("P_PlattformID").Visible = False
griFocusProdukte.Columns("P_ProduktID").ReadOnly = True
griFocusProdukte.Columns("SKU").ReadOnly = True
griFocusProdukte.Columns("P_PlattformID").ReadOnly = True
griFocusProdukte.Columns("Titel").ReadOnly = True
griFocusProdukte.Columns("Plattform").ReadOnly = True
griFocusProdukte.Columns("Status").ReadOnly = True
resizeGrid(griFocusProdukte, False, True)
Dein Konzept mit den zusätzlich hinzugefügten Spalten
im DGV ist alles andere als übersichtlich und könnte
sicher besser gelöst werden.
Schau Dir dazu mal die Beispiele mit dem DataGridView
unter www.gssg.de -> Visual Basic -> VB.net an.
In den meisten dieser Beispiele wird das DGV über ein
DataView - Objekt welches zur zugehörigen DataTable
erstellt wurde an diese DataTable gebunden.
Diese DataTable/DataView sollte in Deinem Fall alle
erforderlichen Spalten enthalten und beim Update, bzw.
Hinzufügen von neuen Datensätzen in der DB sollten
mit einem Command, welcher nur die in der DB
vorhandenen Felder berücksichtigt, die Daten zur DB
übertragen werden.
Post by Christina Heß
Nach diversen Tests habe ich nun herausgefunden, das
der Code fuktioniert, wenn ich ihn ausführe, wenn ich
hinter ein Click-Event eines Buttons packe.
Im Load / Shown / activate Event der Form funktioniert
das nicht.
Im Load-Ereignis der Form ist nicht sichergestellt, dass
die Form und/oder auf dieser enthaltene Steuerelemente
schon vollständig geladen sind. Es sollte deshalb dort
keinen Code geben, der sich auf die Form oder eines
der Steuerelemente dieser Form bezieht.

Im Ereignis Form.Shown sollte es allerdings kein Problem
geben, da dort sichergestellt ist, dass alle Objekte (Form
und Steuerelemente) vollständig geladen sind.

Gruß aus St.Georgen
Peter Götz
www.gssg.de (mit VB-Tipps u. Beispielprogrammen)

Peter Götz
2009-07-09 17:02:07 UTC
Permalink
Hallo Christina,

schau Dir mal das nachfolgende Beispiel an.
Den Code einfach in ein leeres Formmodul (Form1.vb)
kopieren und dann starten.

' /// Code in Formmodul (Form1.vb)
Public Class Form1
Private mDT As DataTable
Private mDV As DataView
Private WithEvents DGV As DataGridView
Private mFlag As Boolean

Private Sub Form1_Load _
(ByVal sender As System.Object, _
ByVal e As System.EventArgs _
) Handles MyBase.Load

DGV = New DataGridView
With DGV
.Dock = DockStyle.Fill
.DefaultCellStyle.Font = _
New Font("Arial", 12)

.ColumnHeadersDefaultCellStyle.Font = _
New Font("Arial", 8, FontStyle.Bold)

End With
Me.Controls.Add(DGV)

CreateData()

DGV.DataSource = mDV

Dim DGVCBcol As New DataGridViewCheckBoxColumn(False)
DGV.Columns.Add(DGVCBcol)
DGV.Columns(3).HeaderText = "Erfassung"

DGV.AutoResizeColumns()

For i As Integer = 0 To 11
DGV.CurrentCell = DGV.Rows(i).Cells(0)
Next

End Sub

Private Sub CreateData()
Dim i As Integer
Dim DR As DataRow

mDT = New DataTable
With mDT
.Columns.Add("ID", GetType(Integer))
.Columns(0).AllowDBNull = False

.Columns.Add("SText", GetType(String))
.Columns.Add("LText", GetType(String))

For i = 1 To 12
DR = .NewRow
DR.Item(0) = i
DR.Item(1) = MonthName(i, True)
DR.Item(2) = MonthName(i, False)
.Rows.Add(DR)
Next
.AcceptChanges()
End With

mDV = New DataView(mDT)


End Sub

Private Sub DGV_CellValidating _
(ByVal sender As Object, _
ByVal e As DataGridViewCellValidatingEventArgs _
) Handles DGV.CellValidating

If Not mFlag Then
If e.ColumnIndex = 2 Then

SetCheckBox(e.RowIndex)
End If
End If
End Sub

Private Sub DGV_RowEnter _
(ByVal sender As Object, _
ByVal e As DataGridViewCellEventArgs _
) Handles DGV.RowEnter

If Not mFlag Then
SetCheckBox(e.RowIndex)
End If
End Sub

Private Sub SetCheckBox(ByVal RowIndex As Integer)
If DGV.Rows.Count > 0 Then
If DGV.Columns.Count > 3 Then
Dim Ccrit As DataGridViewTextBoxCell = _
DirectCast(DGV.Rows(RowIndex).Cells(2), _
DataGridViewTextBoxCell)

Dim Ccbox As DataGridViewCheckBoxCell = _
DirectCast(DGV.Rows(RowIndex).Cells(3), _
DataGridViewCheckBoxCell)

Dim DRV As DataRowView = mDV.Item(RowIndex)
Dim CritValue As String

If Ccrit.EditedFormattedValue.ToString.Length _
0 Then
CritValue = Ccrit.EditedFormattedValue.ToString
mFlag = True

If CritValue.EndsWith _
("r", StringComparison.OrdinalIgnoreCase) Then

DGV.Rows(RowIndex).ReadOnly = True
Ccbox.ThreeState = True
Ccbox.Value = CheckState.Indeterminate
Else
DGV.Rows(RowIndex).ReadOnly = False
Ccbox.ThreeState = False
Ccbox.Value = CheckState.Checked
End If

mFlag = False
End If
End If
End If
End Sub
End Class
' \\\ E N T E _________

Zeilen in denen der Text in Spalte LText mit "r" oder "R"
endet werden gesperrt und die Checkbox bekommt den
Wert CheckState.Indeterminate.

Ich verstehe zwar nicht so ganz, was Du damit bezweckst,
vermute aber mal, dass es das ist, wonach Du suchst.

Weitere Beispiele mit dem DataGridView findest Du
unter

www.gssg.de -> Visual Basic -> VB.net


Gruß aus St.Georgen
Peter Götz
www.gssg.de (mit VB-Tipps u. Beispielprogrammen)
Loading...