none
DataGridView sortieren RRS feed

  • Frage

  • Hallo,

    ich habe hoffentlich 2 kleine Probleme.

    Ich habe ein DataGridView an eine Access-DB angebunden.

    1.) Wie kann ich programmatisch die Auswahl der Datensätze einschränken.

    2.) In der View wird auch eine Spalte mit Auswahlmöglichkeiten dargestellt. Bspw. Branche. In dem Datensatz den ich selektiere steht nur eine ID, die auf die Tabelle Branchen verweist. Wenn ich nun diese Spalte sortiere wird nach der ID sortiert und nicht nach dem angezeigtem Text.

    Danke für jede Hilfe.

    (VS ab 2008)

    --

    Gruß Scotty

    Donnerstag, 11. November 2010 13:56

Antworten

  • Hallo Karsten,
    hier Dein Beispiel überarbeitet und ergänzt mit AddingNew für neue Datensätze bei Nutzung eines BindingSource-Objektes mit nicht-typisiertem DataSet:

    Option Strict On
    
    Public Class MainForm
    
     Private rnd As New Random
    
     Private _DataSet As New DataSet
     Private _BindingSource As BindingSource
    
     Friend WithEvents DataGridView1 As New DataGridView _
       With {.Dock = DockStyle.Fill, .AutoGenerateColumns = False, .MultiSelect = False}
    
     Private Sub FRM_Main_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
      Me.Controls.Add(DataGridView1)
    
      CreateSampleTables()
      CreateSampleRelations()
    
      With DataGridView1
       .DataSource = _BindingSource
    
       .Columns.Add(New DataGridViewTextBoxColumn With {.HeaderText = "Comment", .DataPropertyName = "Comment"})
       .Columns.Add(New DataGridViewComboBoxColumn With {.HeaderText = "ProjectName", .DataPropertyName = "ProjectID", .DataSource = New BindingSource(_DataSet, "Projects"), .DisplayMember = "ProjectName", .ValueMember = "ID", .DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing})
       .Columns.Add(New DataGridViewComboBoxColumn With {.HeaderText = "BusinessAreaName", .DataPropertyName = "BusinessAreaID", .DataSource = New BindingSource(_DataSet, "BusinessAreas"), .DisplayMember = "BusinessAreaName", .ValueMember = "ID", .DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing})
      End With
    
     End Sub
    
     Private Sub DataGridView1_ColumnHeaderMouseClick(ByVal sender As Object, ByVal e As DataGridViewCellMouseEventArgs) Handles DataGridView1.ColumnHeaderMouseClick
      Dim dir = If(_BindingSource.Sort Is Nothing OrElse _BindingSource.Sort.Contains("DESC"), "ASC", "DESC")
      Select Case e.ColumnIndex
       Case 0 : _BindingSource.Sort = "Comment " & dir
       Case 1 : _BindingSource.Sort = "ProjectName " & dir
       Case 2 : _BindingSource.Sort = "BusinessAreaName " & dir
      End Select
     End Sub
    
     Private Sub CreateSampleTables()
    
      With _DataSet.Tables.Add("Projects")
       With .Columns.Add("ID", GetType(System.String))
        .AllowDBNull = False
        .MaxLength = 50
        .Unique = True
       End With
       With .Columns.Add("ProjectName", GetType(System.String))
        .AllowDBNull = False
        .MaxLength = 50
        .Unique = True
       End With
       Dim newRow = .NewRow
       newRow("ID") = Guid.NewGuid.ToString
       newRow("ProjectName") = ""
       .Rows.Add(newRow)
       For n = 0 To 7
        newRow = .NewRow
        newRow("ID") = Guid.NewGuid.ToString
        newRow("ProjectName") = "Project " & (n + 1).ToString
        .Rows.Add(newRow)
       Next
      End With
    
      With _DataSet.Tables.Add("BusinessAreas")
       With .Columns.Add("ID", GetType(System.String))
        .AllowDBNull = False
        .MaxLength = 50
        .Unique = True
       End With
       With .Columns.Add("BusinessAreaName", GetType(System.String))
        .AllowDBNull = False
        .MaxLength = 50
        .Unique = True
       End With
       Dim newRow = .NewRow
       newRow("ID") = Guid.NewGuid.ToString
       newRow("BusinessAreaName") = ""
       .Rows.Add(newRow)
       For n = 0 To 7
        newRow = .NewRow
        newRow("ID") = Guid.NewGuid.ToString
        newRow("BusinessAreaName") = "BusinessArea " & (n + 1).ToString
        .Rows.Add(newRow)
       Next
      End With
    
      With _DataSet.Tables.Add("Tasks")
       With .Columns.Add("ID", GetType(System.String))
        .AllowDBNull = False
        .MaxLength = 50
        .Unique = True
       End With
       With .Columns.Add("ProjectID", GetType(System.String))
        .AllowDBNull = False
        .MaxLength = 50
        .Unique = False
       End With
       With .Columns.Add("BusinessAreaID", GetType(System.String))
        .AllowDBNull = False
        .MaxLength = 50
        .Unique = False
       End With
       With .Columns.Add("Comment", GetType(System.String))
        .AllowDBNull = True
        .MaxLength = 50
        .Unique = False
       End With
       For n = 0 To 19
        Dim newRow = .NewRow
        newRow("ID") = Guid.NewGuid.ToString
        Dim i As Integer = Rnd.Next(_DataSet.Tables("Projects").Rows.Count)
        newRow("ProjectID") = _DataSet.Tables("Projects").Rows(i)("ID")
        i = Rnd.Next(_DataSet.Tables("BusinessAreas").Rows.Count)
        newRow("BusinessAreaID") = _DataSet.Tables("BusinessAreas").Rows(i)("ID")
        newRow("Comment") = "Comment " & (n + 1).ToString
        .Rows.Add(newRow)
       Next
      End With
    
     End Sub
    
     Private Sub CreateSampleRelations()
      With _DataSet
       .Relations.Add("Tasks_Projects", .Tables("Projects").Columns("ID"), .Tables("Tasks").Columns("ProjectID"))
       .Relations.Add("Tasks_BusinessAreas", .Tables("BusinessAreas").Columns("ID"), .Tables("Tasks").Columns("BusinessAreaID"))
       .Tables("Tasks").Columns.Add("ProjectName", GetType(String), "Parent(Tasks_Projects).ProjectName")
       .Tables("Tasks").Columns.Add("BusinessAreaName", GetType(String), "Parent(Tasks_BusinessAreas).BusinessAreaName")
      End With
      _BindingSource = New BindingSource(_DataSet, "Tasks")
      AddHandler _BindingSource.AddingNew, AddressOf newRow
     End Sub
    
     Private Sub NewRow(ByVal sender As Object, ByVal e As System.ComponentModel.AddingNewEventArgs)
      Static sw As Boolean = False
      If sw Then Exit Sub
      sw = True
      Dim newRow = CType(Me._BindingSource.AddNew, DataRowView)
      newRow("ID") = Guid.NewGuid.ToString
      Dim i As Integer = rnd.Next(_DataSet.Tables("Projects").Rows.Count)
      newRow("ProjectID") = _DataSet.Tables("Projects").Rows(i)("ID")
      i = rnd.Next(_DataSet.Tables("BusinessAreas").Rows.Count)
      newRow("BusinessAreaID") = _DataSet.Tables("BusinessAreas").Rows(i)("ID")
      newRow("Comment") = ""
      e.NewObject = newRow
      sw = False
     End Sub
    
    End Class
    

    --
    Peter 

    • Als Antwort vorgeschlagen Peter Fleischer Montag, 15. November 2010 05:23
    • Als Antwort markiert Karsten Sosna Montag, 15. November 2010 18:04
    Montag, 15. November 2010 05:22

Alle Antworten

  • Hallo Karsten,

    1.) Wie kann ich programmatisch die Auswahl der Datensätze einschränken.

    wo willst Du die Einschränkung erledigen. Direkt im SQL Statement, mit welchem Du die Daten ausliest? In dem Fall müsstest Du das Statement lediglich so aufbauen:

    SELECT ... FROM ... WHERE Spalte1 = ? AND Spalte2 = ? ...

    Und danach dann Parameterobjekte mit den Filterwerten integrieren.

    Siehe auch:

      http://msdn.microsoft.com/de-de/library/system.data.oledb.oledbcommand.parameters.aspx

    Wie bindest Du die Daten eigentlich? Per DataTable? In dem Fall könntest Du auch mit <DataTable>.DefaultView.RowFilter = ... arbeiten.

    2.) In der View wird auch eine Spalte mit Auswahlmöglichkeiten dargestellt. Bspw. Branche. In dem Datensatz den ich selektiere steht nur eine ID, die auf die Tabelle Branchen verweist. Wenn ich nun diese Spalte sortiere wird nach der ID sortiert und nicht nach dem angezeigtem Text.

    Das ist normal, da in Access in dieser Spalte nur die Zahl steht, nicht der Textwert. In dem Fall müsstest Du bspw. in Access (oder per SQL Statement in deiner Anwendung) eine neue Abfrage aufbauen, die den zugehörigen Text mit ausliest:

      SELECT a.ID, a.Name, a.TypeId, t.Name AS TypeName FROM Articles a, Types t WHERE a.TypeId = t.ID

    Das wäre ein Beispiel für eine solche Abfrage. Du kannst dann nach der Spalte "TypeName" (ist ein Aliasname für Types.Name im Beispiel) sortieren, filtern, ...

     

     


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
    Donnerstag, 11. November 2010 20:17
    Moderator
  • Hallo Stefan,

    vorab, ich habe die Bindung mit dem Assistenten erstellt. Danach habe ich dann ein DataSet-, TableAdapter-, mehrere BindingSource- und mehrere DataAdapter-Objekte. Ach ja und die Datensätze werden in einem DataGridView angezeigt.

    Schön wäre es wenn ich die Abfrage parametrisieren könnte und zur Laufzeit dann nur den Filter zu weisen bräuchte. Mir fehlt hier aber völlig der Ansatz.

    Was das Sortieren betrifft, so habe ich mir das schon fast gedacht, dass ich mit einem Alias arbeiten muss. nun ich werd das mal versuchen.

    --

    Gruß Scotty

    Freitag, 12. November 2010 06:55
  • Hallo Karsten,

    vorab, ich habe die Bindung mit dem Assistenten erstellt.

    Aua.

    Schön wäre es wenn ich die Abfrage parametrisieren könnte und zur Laufzeit dann nur den Filter zu weisen bräuchte. Mir fehlt hier aber völlig der Ansatz.

    Du kannst die Abfrage(n) mit Parametern versehen. Wie man das per Klicki-Klacki macht, weiß ich nicht. Codeseitig geht das wie oben schon gezeigt mit Parametern im SQL Statement, also bspw.:

      SELECT ... FROM ... WHERE Spalte1 = ? AND Spalte2 = ? ...

    Ein Beispiel dafür findest Du hier:

      http://www.aspnetzone.de/blogs/stefanfalz/archive/2010/04/23/OleDb-Parameter-fuer-OleDbCommand-muessen-zwingend-in-Reihenfolge-sein-Fragezeichen.aspx

    Was das Sortieren betrifft, so habe ich mir das schon fast gedacht, dass ich mit einem Alias arbeiten muss. nun ich werd das mal versuchen.

    Im Endeffekt ist es das einfachste, wenn Du die Abfrage direkt in Access erstellst, dann kannst Du die auch über den Assistenten in Visual Studio sehen und als Datenquelle angeben.

     


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
    Freitag, 12. November 2010 12:01
    Moderator
  • Hallo Stefan,

    auch wenn es "verpöhnt" ist den Disgner zu bemühen, aber "Aua" ist das bestimmt nicht. Geradeim Bereich von Abfragen kann er eine Menge vorleisten, die man sonst "von Hand" tun müsste. Da müssen Objekte erstelltund parametrisiert werden,die Du auf dem "normalen Weg"doch sehr zeitintensiv erstellst. Ich wählebei meinen Anfragen im recht einfache Beispiele,damit nchvollziehen kann was ich vor habe. Am Ende ist das Endziel doch bei weiten viel größer. In dem Aktuellen Projekt besteht die Datenbank aus 23 Tabellen, die alle in Beziehungen zueinander stehen. Hier die passenden Abfragen zu erstellen stellt wohl weniger das Problem dar, es sind die Commands wie Update, Insert und Delete. Der Assistent schafft dort nun mal ein Grundlage.

    Nun ich werde es weiter über den Assistenten probieren.

    --

    Gruß Scotty

    Freitag, 12. November 2010 18:00
  • Hi Karsten,
    das Sortieren kannst Du mit einem Headerklick organisieren, z.B. so:

    Public Class MainForm
    
     Dim bs As BindingSource
    
     Private Sub MainForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
      Dim dgv As New DataGridView With {.Dock = DockStyle.Fill}
      AddHandler dgv.ColumnHeaderMouseClick, AddressOf dgv_ColumnHeaderMouseClick
      Me.Controls.Add(dgv)
      With TestData.GetDataSet
       .Relations.Add("rel1", .Tables("Tab1").Columns("ID"), .Tables("Tab2").Columns("FK"))
       .Tables("Tab2").Columns.Add("Master", GetType(String), "Parent(rel1).Col1")
      End With
      bs = TestData.GetBindingSource2
      With dgv
       .AutoGenerateColumns = False
       .DataSource = bs
       .Columns.Add(New DataGridViewTextBoxColumn With {.HeaderText = "FK", .DataPropertyName = "FK"})
       .Columns.Add(New DataGridViewComboBoxColumn With {.HeaderText = "Master", .DataPropertyName = "FK", _
                                .DataSource = TestData.GetBindingSource1, _
                                .DisplayMember = "col1", _
                                .ValueMember = "ID"})
      End With
     End Sub
    
     Private Sub dgv_ColumnHeaderMouseClick(ByVal sender As Object, ByVal e As DataGridViewCellMouseEventArgs)
      If e.ColumnIndex = 1 Then
       bs.Sort = "Master"
      End If
     End Sub
    
    End Class
    
    ' Und die Datenklasse dazu, die aber auch mit dem designer erzeugt werden kann.
    
    Public Class TestData
    
     Shared ds As New DataSet
    
     Shared bs1, bs2 As BindingSource
    
     Shared Sub New()
      LoadDataSet()
     End Sub
    
     Shared Sub LoadDataSet()
      Dim i, k As Integer
      Dim s As String
      ds.Tables.Add(New DataTable("Tab1"))
      With ds.Tables("Tab1")
       With .Columns
        .Add(New DataColumn("ID", GetType(Int32)))
        With .Item(0)
         .AutoIncrement = True
         .AutoIncrementSeed = 1
         .AutoIncrementStep = 1
        End With
        .Add(New DataColumn("col1", GetType(String)))
        .Add(New DataColumn("col2", GetType(String)))
       End With
       For i = 1 To 10
        Dim r1 As DataRow = .NewRow
        With r1
         .Item(1) = i.ToString & ". Row"
         s = ""
         For k = 1 To CInt(20 * Rnd())
          s &= Chr(65 + CInt(26 * Rnd()))
         Next
         .Item(2) = s
        End With
        .Rows.Add(r1)
       Next
       .AcceptChanges()
      End With
      ds.Tables.Add(New DataTable("Tab2"))
      With ds.Tables("Tab2")
       With .Columns
        .Add(New DataColumn("ID", GetType(Int32)))
        With .Item(0)
         .AutoIncrement = True
         .AutoIncrementSeed = 1
         .AutoIncrementStep = 1
        End With
        .Add(New DataColumn("FK", GetType(Integer)))
        .Add(New DataColumn("col2", GetType(String)))
       End With
       For i = 1 To 200
        Dim r2 As DataRow = .NewRow
        With r2
         .Item(1) = CInt(0.5 + 10 * Rnd())
         .Item(2) = "Child-Row " & i.ToString
        End With
        .Rows.Add(r2)
       Next
       .AcceptChanges()
      End With
      bs1 = New BindingSource(ds, "Tab1")
      bs2 = New BindingSource(ds, "Tab2")
     End Sub
    
     Shared Function GetBindingSource1() As BindingSource
      Return bs1
     End Function
    
     Shared Function GetBindingSource2() As BindingSource
      Return bs2
     End Function
    
     Shared Function GetDataSet() As DataSet
      Return ds
     End Function
    
    End Class
    
    --
    Peter

     

    • Als Antwort vorgeschlagen Peter Fleischer Montag, 15. November 2010 05:23
    Freitag, 12. November 2010 21:00
  • Hallo Peter,

    auf Dich habe ich gewartet. ;=)

    Wenn sich jemmand damit auskennt, dann bestimmt Du.

    Danke erstmalfür Dein Beispiel, ich habe das maletwas umgebaut, damt ichden Bezug nicht verliere. Hier meine Source:

    Public Class FRM_Main
    
    	Private _DataSet As New DataSet
    	Private _BindingSource As BindingSource
    
    	Friend WithEvents DataGridView1 As New DataGridView With {.Dock = DockStyle.Fill}
    
    	Private Sub FRM_Main_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    		Me.Controls.Add(DataGridView1)
    
    		CreateSampleTables()
    		CreateSampleRelations()
    
    		With DataGridView1
    			.AutoGenerateColumns = False
    			.MultiSelect = False
    			.DataSource = _BindingSource
    
    			.Columns.Add(New DataGridViewTextBoxColumn With {.HeaderText = "Comment", .DataPropertyName = "Comment"})
    			.Columns.Add(New DataGridViewComboBoxColumn With {.HeaderText = "ProjectName", .DataPropertyName = "ProjectID", .DataSource = New BindingSource(_DataSet, "Projects"), .DisplayMember = "ProjectName", .ValueMember = "ID", .DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing})
    			.Columns.Add(New DataGridViewComboBoxColumn With {.HeaderText = "BusinessAreaName", .DataPropertyName = "BusinessAreaID", .DataSource = New BindingSource(_DataSet, "BusinessAreas"), .DisplayMember = "BusinessAreaName", .ValueMember = "ID", .DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing})
    		End With
    
    	End Sub
    
    	Private Sub DataGridView1_ColumnHeaderMouseClick(ByVal sender As Object, ByVal e As DataGridViewCellMouseEventArgs) Handles DataGridView1.ColumnHeaderMouseClick
    		Select Case e.ColumnIndex
    			Case 0
    				If _BindingSource.Sort = "Comment ASC" Then
    					_BindingSource.Sort = "Comment DESC"
    				Else
    					_BindingSource.Sort = "Comment ASC"
    				End If
    			Case 1
    				If _BindingSource.Sort = "ProjectName ASC" Then
    					_BindingSource.Sort = "ProjectName DESC"
    				Else
    					_BindingSource.Sort = "ProjectName ASC"
    				End If
    			Case 2
    				If _BindingSource.Sort = "BusinessAreaName ASC" Then
    					_BindingSource.Sort = "BusinessAreaName DESC"
    				Else
    					_BindingSource.Sort = "BusinessAreaName ASC"
    				End If
    		End Select
    	End Sub
    
    	Private Sub CreateSampleTables()
    
    		Dim rnd As New Random
    
    		_DataSet.Tables.Add("Projects")
    		With _DataSet.Tables("Projects")
    
    			Dim newCol As DataColumn
    
    			newCol = .Columns.Add("ID", GetType(System.String))
    			With newCol
    				.AllowDBNull = False
    				.MaxLength = 50
    				.Unique = True
    			End With
    
    			newCol = .Columns.Add("ProjectName", GetType(System.String))
    			With newCol
    				.AllowDBNull = False
    				.MaxLength = 50
    				.Unique = True
    			End With
    
    			Dim newRow As DataRow
    			newRow = .NewRow
    
    			newRow("ID") = Guid.NewGuid.ToString
    
    			newRow("ProjectName") = ""
    			.Rows.Add(newRow)
    
    			For n = 0 To 7
    
    				newRow = .NewRow
    
    				newRow("ID") = Guid.NewGuid.ToString
    
    				newRow("ProjectName") = "Project " & (n + 1).ToString
    				.Rows.Add(newRow)
    
    			Next
    
    		End With
    
    		_DataSet.Tables.Add("BusinessAreas")
    		With _DataSet.Tables("BusinessAreas")
    
    			Dim newCol As DataColumn
    
    			newCol = .Columns.Add("ID", GetType(System.String))
    			With newCol
    				.AllowDBNull = False
    				.MaxLength = 50
    				.Unique = True
    			End With
    
    			newCol = .Columns.Add("BusinessAreaName", GetType(System.String))
    			With newCol
    				.AllowDBNull = False
    				.MaxLength = 50
    				.Unique = True
    			End With
    
    			Dim newRow As DataRow
    			newRow = .NewRow
    
    			newRow("ID") = Guid.NewGuid.ToString
    
    			newRow("BusinessAreaName") = ""
    
    			.Rows.Add(newRow)
    
    			For n = 0 To 7
    
    				newRow = .NewRow
    
    				newRow("ID") = Guid.NewGuid.ToString
    
    				newRow("BusinessAreaName") = "BusinessArea " & (n + 1).ToString
    				.Rows.Add(newRow)
    
    			Next
    
    		End With
    
    		_DataSet.Tables.Add("Tasks")
    		With _DataSet.Tables("Tasks")
    
    			Dim newCol As DataColumn
    
    			newCol = .Columns.Add("ID", GetType(System.String))
    			With newCol
    				.AllowDBNull = False
    				.MaxLength = 50
    				.Unique = True
    			End With
    
    			newCol = .Columns.Add("ProjectID", GetType(System.String))
    			With newCol
    				.AllowDBNull = False
    				.MaxLength = 50
    				.Unique = False
    			End With
    
    			newCol = .Columns.Add("BusinessAreaID", GetType(System.String))
    			With newCol
    				.AllowDBNull = False
    				.MaxLength = 50
    				.Unique = False
    			End With
    
    			newCol = .Columns.Add("Comment", GetType(System.String))
    			With newCol
    				.AllowDBNull = True
    				.MaxLength = 50
    				.Unique = False
    			End With
    
    			For n = 0 To 19
    				Dim newRow As DataRow
    
    				newRow = .NewRow
    
    				newRow("ID") = Guid.NewGuid.ToString
    
    				Dim i As Integer
    
    				i = rnd.Next(_DataSet.Tables("Projects").Rows.Count)
    				newRow("ProjectID") = _DataSet.Tables("Projects").Rows(i)("ID")
    
    				i = rnd.Next(_DataSet.Tables("BusinessAreas").Rows.Count)
    				newRow("BusinessAreaID") = _DataSet.Tables("BusinessAreas").Rows(i)("ID")
    
    				newRow("Comment") = "Comment " & (n + 1).ToString
    				.Rows.Add(newRow)
    
    			Next
    		End With
    
    	End Sub
    
    	Private Sub CreateSampleRelations()
    
    		With _DataSet
    			.Relations.Add("Tasks_Projects", .Tables("Projects").Columns("ID"), .Tables("Tasks").Columns("ProjectID"))
    			.Relations.Add("Tasks_BusinessAreas", .Tables("BusinessAreas").Columns("ID"), .Tables("Tasks").Columns("BusinessAreaID"))
    			.Tables("Tasks").Columns.Add("ProjectName", GetType(String), "Parent(Tasks_Projects).ProjectName")
    			.Tables("Tasks").Columns.Add("BusinessAreaName", GetType(String), "Parent(Tasks_BusinessAreas).BusinessAreaName")
    		End With
    
    		_BindingSource = New BindingSource(_DataSet, "Tasks")
    	End Sub
    
    End Class
    

    Sieht etwas viel aus, ist aber im Eigentlichen gar nicht.

    Nun möchte ich von meinem eigentlich Design abweichen,ich dachte die Datensätze nur in Detailansich zu ändern. Nun mit dieser Variante kann ich die Datensätze auch direkt ändern, schon mal eine gute Sache, gefällt mir ganz gut. Ich kann so aber auch Datensätze hinzufügen, auch eine gute Sache. Jedoch habe ich hier ein Problem bei der "Tasks-Table". Die ID wird nicht angezeigt muss aber vorhanden und eindeutig sein. Ähnliches für die Spalten "ProjectID" und "BusinessAreaID", diese müssen mit gültigen Werten gefüllt sein.

    Welches ist nun das naheliegenstes Ereignis um auf das Hinzufügen von Datensätzen zu reagieren,damit ich die GUID für ID erzeugen kann?

    --

    Gruß Scotty

     

    Samstag, 13. November 2010 07:13
  • Hallo Karsten,
    hier Dein Beispiel überarbeitet und ergänzt mit AddingNew für neue Datensätze bei Nutzung eines BindingSource-Objektes mit nicht-typisiertem DataSet:

    Option Strict On
    
    Public Class MainForm
    
     Private rnd As New Random
    
     Private _DataSet As New DataSet
     Private _BindingSource As BindingSource
    
     Friend WithEvents DataGridView1 As New DataGridView _
       With {.Dock = DockStyle.Fill, .AutoGenerateColumns = False, .MultiSelect = False}
    
     Private Sub FRM_Main_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
      Me.Controls.Add(DataGridView1)
    
      CreateSampleTables()
      CreateSampleRelations()
    
      With DataGridView1
       .DataSource = _BindingSource
    
       .Columns.Add(New DataGridViewTextBoxColumn With {.HeaderText = "Comment", .DataPropertyName = "Comment"})
       .Columns.Add(New DataGridViewComboBoxColumn With {.HeaderText = "ProjectName", .DataPropertyName = "ProjectID", .DataSource = New BindingSource(_DataSet, "Projects"), .DisplayMember = "ProjectName", .ValueMember = "ID", .DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing})
       .Columns.Add(New DataGridViewComboBoxColumn With {.HeaderText = "BusinessAreaName", .DataPropertyName = "BusinessAreaID", .DataSource = New BindingSource(_DataSet, "BusinessAreas"), .DisplayMember = "BusinessAreaName", .ValueMember = "ID", .DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing})
      End With
    
     End Sub
    
     Private Sub DataGridView1_ColumnHeaderMouseClick(ByVal sender As Object, ByVal e As DataGridViewCellMouseEventArgs) Handles DataGridView1.ColumnHeaderMouseClick
      Dim dir = If(_BindingSource.Sort Is Nothing OrElse _BindingSource.Sort.Contains("DESC"), "ASC", "DESC")
      Select Case e.ColumnIndex
       Case 0 : _BindingSource.Sort = "Comment " & dir
       Case 1 : _BindingSource.Sort = "ProjectName " & dir
       Case 2 : _BindingSource.Sort = "BusinessAreaName " & dir
      End Select
     End Sub
    
     Private Sub CreateSampleTables()
    
      With _DataSet.Tables.Add("Projects")
       With .Columns.Add("ID", GetType(System.String))
        .AllowDBNull = False
        .MaxLength = 50
        .Unique = True
       End With
       With .Columns.Add("ProjectName", GetType(System.String))
        .AllowDBNull = False
        .MaxLength = 50
        .Unique = True
       End With
       Dim newRow = .NewRow
       newRow("ID") = Guid.NewGuid.ToString
       newRow("ProjectName") = ""
       .Rows.Add(newRow)
       For n = 0 To 7
        newRow = .NewRow
        newRow("ID") = Guid.NewGuid.ToString
        newRow("ProjectName") = "Project " & (n + 1).ToString
        .Rows.Add(newRow)
       Next
      End With
    
      With _DataSet.Tables.Add("BusinessAreas")
       With .Columns.Add("ID", GetType(System.String))
        .AllowDBNull = False
        .MaxLength = 50
        .Unique = True
       End With
       With .Columns.Add("BusinessAreaName", GetType(System.String))
        .AllowDBNull = False
        .MaxLength = 50
        .Unique = True
       End With
       Dim newRow = .NewRow
       newRow("ID") = Guid.NewGuid.ToString
       newRow("BusinessAreaName") = ""
       .Rows.Add(newRow)
       For n = 0 To 7
        newRow = .NewRow
        newRow("ID") = Guid.NewGuid.ToString
        newRow("BusinessAreaName") = "BusinessArea " & (n + 1).ToString
        .Rows.Add(newRow)
       Next
      End With
    
      With _DataSet.Tables.Add("Tasks")
       With .Columns.Add("ID", GetType(System.String))
        .AllowDBNull = False
        .MaxLength = 50
        .Unique = True
       End With
       With .Columns.Add("ProjectID", GetType(System.String))
        .AllowDBNull = False
        .MaxLength = 50
        .Unique = False
       End With
       With .Columns.Add("BusinessAreaID", GetType(System.String))
        .AllowDBNull = False
        .MaxLength = 50
        .Unique = False
       End With
       With .Columns.Add("Comment", GetType(System.String))
        .AllowDBNull = True
        .MaxLength = 50
        .Unique = False
       End With
       For n = 0 To 19
        Dim newRow = .NewRow
        newRow("ID") = Guid.NewGuid.ToString
        Dim i As Integer = Rnd.Next(_DataSet.Tables("Projects").Rows.Count)
        newRow("ProjectID") = _DataSet.Tables("Projects").Rows(i)("ID")
        i = Rnd.Next(_DataSet.Tables("BusinessAreas").Rows.Count)
        newRow("BusinessAreaID") = _DataSet.Tables("BusinessAreas").Rows(i)("ID")
        newRow("Comment") = "Comment " & (n + 1).ToString
        .Rows.Add(newRow)
       Next
      End With
    
     End Sub
    
     Private Sub CreateSampleRelations()
      With _DataSet
       .Relations.Add("Tasks_Projects", .Tables("Projects").Columns("ID"), .Tables("Tasks").Columns("ProjectID"))
       .Relations.Add("Tasks_BusinessAreas", .Tables("BusinessAreas").Columns("ID"), .Tables("Tasks").Columns("BusinessAreaID"))
       .Tables("Tasks").Columns.Add("ProjectName", GetType(String), "Parent(Tasks_Projects).ProjectName")
       .Tables("Tasks").Columns.Add("BusinessAreaName", GetType(String), "Parent(Tasks_BusinessAreas).BusinessAreaName")
      End With
      _BindingSource = New BindingSource(_DataSet, "Tasks")
      AddHandler _BindingSource.AddingNew, AddressOf newRow
     End Sub
    
     Private Sub NewRow(ByVal sender As Object, ByVal e As System.ComponentModel.AddingNewEventArgs)
      Static sw As Boolean = False
      If sw Then Exit Sub
      sw = True
      Dim newRow = CType(Me._BindingSource.AddNew, DataRowView)
      newRow("ID") = Guid.NewGuid.ToString
      Dim i As Integer = rnd.Next(_DataSet.Tables("Projects").Rows.Count)
      newRow("ProjectID") = _DataSet.Tables("Projects").Rows(i)("ID")
      i = rnd.Next(_DataSet.Tables("BusinessAreas").Rows.Count)
      newRow("BusinessAreaID") = _DataSet.Tables("BusinessAreas").Rows(i)("ID")
      newRow("Comment") = ""
      e.NewObject = newRow
      sw = False
     End Sub
    
    End Class
    

    --
    Peter 

    • Als Antwort vorgeschlagen Peter Fleischer Montag, 15. November 2010 05:23
    • Als Antwort markiert Karsten Sosna Montag, 15. November 2010 18:04
    Montag, 15. November 2010 05:22
  •  Private Sub CreateSampleRelations()

      With _DataSet .Relations.Add("Tasks_Projects", .Tables("Projects").Columns("ID"), .Tables("Tasks").Columns("ProjectID"))

       .Relations.Add("Tasks_BusinessAreas", .Tables("BusinessAreas").Columns("ID"), .Tables("Tasks").Columns("BusinessAreaID"))

       .Tables("Tasks").Columns.Add("ProjectName", GetType(String), "Parent(Tasks_Projects).ProjectName")

       .Tables("Tasks").Columns.Add("BusinessAreaName", GetType(String), "Parent(Tasks_BusinessAreas).BusinessAreaName")

      End With

      _BindingSource = New BindingSource(_DataSet, "Tasks")

      AddHandler _BindingSource.AddingNew, AddressOf newRow

    End Sub



    Private Sub NewRow(ByVal sender As Object, ByVal e As System.ComponentModel.AddingNewEventArgs)

      Static sw As Boolean = False

      If sw Then Exit Sub

      sw = True

      Dim newRow = CType(Me._BindingSource.AddNew, DataRowView) newRow("ID") = Guid.NewGuid.ToString

      Dim i As Integer = rnd.Next(_DataSet.Tables("Projects").Rows.Count)

      newRow("ProjectID") = _DataSet.Tables("Projects").Rows(i)("ID")

      i = rnd.Next(_DataSet.Tables("BusinessAreas").Rows.Count)

      newRow("BusinessAreaID") = _DataSet.Tables("BusinessAreas").Rows(i)("ID")

      newRow("Comment") = ""

      e.NewObject = newRow

      sw = False

    End Sub

     

    Hallo Peter,

    rechtherzlichen Dank, ich glaube da hätte ich vorerst nicht gesucht. Ich sag ja, wenn sich einer damit auskennt, dann Du.

    Nochmals Danke

    --

    Gruß Scotty

    Montag, 15. November 2010 18:04