none
Open Form with paramter for filter [VS 2010 VB .Net 4 WindowsForms ] RRS feed

  • Frage

  • Hallo Entwickler,

    hat jemand ein Beispiel in dem eine key id (aus der parent table) fuer eine Tablelle (child table) and ide Form uebergeben wird.

    Damit soll ein Filter gestezt werden.  Wie kann im Fall von INSERT der paramter and den foreign key gebunden werden ?

    Danke

    Rolf

    Mittwoch, 17. November 2010 08:51

Antworten

  • Hallo Rolf,

    in der Folge drei Varianten, die mir so im Laufe der Zeit eingefallen sind.

    Die Beispiele basieren auf der Northwind.Products, gefiltert über eine ToolStripComboBox
    (in Gedenken an einen anderen Thread ;-), deren Einstellung auch für die Vorgabe verwendet wird.
    Denn den Filter selbst kann nur schwer auswerten kann, weil es nunmal eine Zeichenkette ist -
    und man sollte eine zusätzliche Quelle haben.

    Variante 1 verwendet das BindingSource.AddingNew Ereignis und ist am nächsten an der
    BindingSource dran, und dann sinnvoll wenn man unterschiedliche Behandlungen benötigt:

     Private Sub ProductsBindingSource_AddingNew(ByVal sender As System.Object, ByVal e As System.ComponentModel.AddingNewEventArgs) _
        Handles ProductsBindingSource.AddingNew
        Try
          ' Neue Zeile über DataView 
          Dim newRow = DirectCast(Me.ProductsBindingSource.List, DataView).AddNew()
    
          ' Hier aus einem Filter ComboBox
          Dim rowView = TryCast(categoryFilterToolStripComboBox.SelectedItem, DataRowView)
          If rowView IsNot Nothing Then
            newRow("CategoryID") = CInt(rowView("CategoryID"))
    
            ' weitere Vorgaben
            newRow("Discontinued") = False
    
            ' alternativ typisiert
            ' Dim row = DirectCast(newRow.Row, NorthwindDataSet.ProductsRow)
            ' row.CategoryID = DirectCast(rowView.Row, NorthwindDataSet.CategoriesRow).CategoryID
          End If
          ' als Vorgabe zurück
          e.NewObject = newRow
          ' durch AddNew bereits eingefügt, hier positionieren
          Me.ProductsBindingSource.Position = Me.ProductsBindingSource.Count - 1
    
        Catch ex As Exception
          MessageBox.Show(Me, ex.Message)
        End Try
      End Sub
    
    Einige Dinge die dabei zu beachten sind:

    Da gebundene Liste hier eine DataView ist, muß man die neue Zeile darüber erzeugen -
    DataTable.NewRow würde nicht funktionieren).
    Die so erzeugte Zeile muß man dem Ereignisargument NewObject zuweisen.

    Die BindingSource erkennt das einfügen (anhand eines Vergleichs der Listegröße),
    positioniert in dem Falle aber nicht neu, deswegen muß man die Position in dem Falle selbst setzen.

     

    Variante 2 wäre die DefaultValue Eigenschaft für die jeweilige DataColumn zu setzen.
    Entsprechend zum obigen Beispiel (beim Wechseln der ComboBox-Auswahl):

      Private Sub categoryFilterToolStripComboBox_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) _
        Handles categoryFilterToolStripComboBox.SelectedIndexChanged
        Dim rowView = TryCast(categoryFilterToolStripComboBox.SelectedItem, DataRowView)
        If rowView IsNot Nothing Then
          Me.ProductsBindingSource.Filter = String.Format("CategoryID = {0}", rowView("CategoryID"))
    
          ' Zum Standardwert machen
          Me.NorthwindDataSet.Products.CategoryIDColumn.DefaultValue = rowView("CategoryID")
    
        End If
      End Sub
    
    

     

    Variante drei nutzt das DataTable.TableNewRow Ereignis , hier im Formular Konstruktor eingehängt:

     

      Public Sub New()
        InitializeComponent()
    
        AddHandler Me.NorthwindDataSet.Products.TableNewRow, AddressOf ProductsDataTable_TableNewRow
      End Sub
    
      Private Sub ProductsDataTable_TableNewRow(ByVal sender As Object, ByVal e As System.Data.DataTableNewRowEventArgs)
        Dim row = DirectCast(e.Row, NorthwindDataSet.ProductsRow)
    
        row.Discontinued = False
    
        Dim rowView = TryCast(categoryFilterToolStripComboBox.SelectedItem, DataRowView)
        If rowView IsNot Nothing Then
          ' aktuelle Auswahl zuweisen
          row.CategoryID = CInt(rowView("CategoryID"))
        End If
      End Sub
    
    
    

     

    Für die Verknüpfung von Formularen (z. B. einem Detailformular) käme der Ansatz 
    zum Tragen wie bereits diskutiert in
    DataGridView parent child with .NET 4 Was ist der letzte Stand ? {VS 2010 .NET 4 VB WindowsForms ]

    Und nein, keines der Beispiele kommt nur mit IDE aus, was aber nicht die Maßgabe sein sollte.

    Gruß Elmar

    Freitag, 19. November 2010 17:47
    Beantworter

Alle Antworten

  • Hallo Rolf,

    könntest Du das etwas präzisieren?
    Insbesondere mit dem letzten Satz habe ich so meine Schwierigkeiten.

    Gruß Elmar

    Donnerstag, 18. November 2010 10:04
    Beantworter
  • Hallo Elmar,

    bitte entschuldige den Telegrammstil, ich war wohl sehr in Eile. Also nochmal und hoffentlich etwas besser:
    Ich habe mir ein simples DataGrid(View) zusammengeclickt ( DataSet auf die Form gezogen). Dann habe ich in inder IDE (GUI) den Filter paramter (z.B HarwareSelection_ID = 4 ) gesetzt. Folglich bekomme ich nur Recodrs die mit diesem ForeignKey.
    Dann moechte ich eine neuen record addieren , was natuerlich nicht geht da die Texbox fuer den forein key
    (HarwareSelection_ID = 4 ) nicht mit 4 vorbesetzt wird. Das Binding ist ja nicht vom parent table abhaengig, sondern nur von der zu bearbeitenden Tabelle.

    Mein Ziel ist einfach beim Aufruf der Form (.show() ) einen Parameter (eben die ID) zu uebergeben und damit den Filter per code zu setzen. Aber , wie gesagt ich muesste ja anders binden (eben binding des parent table mit relation) um die ID nach AddNew in der Textbox zu sehen.
    Wie geh ich am besten vor:
    Binding irgenwie ueberschreiben ?
    Im TableAdater irgenwie den Wert 4 setzen ? ( Die textbox fuer die ID will ich eigentlich gar nicht sehen)

    Da ich sehr of diese einfachAnwendung habe waere es schoen moeglichts die IDE zu nutzen.

    Danke

    Rolf

     

    Donnerstag, 18. November 2010 12:13
  • Hallo Rolf,

    in der Folge drei Varianten, die mir so im Laufe der Zeit eingefallen sind.

    Die Beispiele basieren auf der Northwind.Products, gefiltert über eine ToolStripComboBox
    (in Gedenken an einen anderen Thread ;-), deren Einstellung auch für die Vorgabe verwendet wird.
    Denn den Filter selbst kann nur schwer auswerten kann, weil es nunmal eine Zeichenkette ist -
    und man sollte eine zusätzliche Quelle haben.

    Variante 1 verwendet das BindingSource.AddingNew Ereignis und ist am nächsten an der
    BindingSource dran, und dann sinnvoll wenn man unterschiedliche Behandlungen benötigt:

     Private Sub ProductsBindingSource_AddingNew(ByVal sender As System.Object, ByVal e As System.ComponentModel.AddingNewEventArgs) _
        Handles ProductsBindingSource.AddingNew
        Try
          ' Neue Zeile über DataView 
          Dim newRow = DirectCast(Me.ProductsBindingSource.List, DataView).AddNew()
    
          ' Hier aus einem Filter ComboBox
          Dim rowView = TryCast(categoryFilterToolStripComboBox.SelectedItem, DataRowView)
          If rowView IsNot Nothing Then
            newRow("CategoryID") = CInt(rowView("CategoryID"))
    
            ' weitere Vorgaben
            newRow("Discontinued") = False
    
            ' alternativ typisiert
            ' Dim row = DirectCast(newRow.Row, NorthwindDataSet.ProductsRow)
            ' row.CategoryID = DirectCast(rowView.Row, NorthwindDataSet.CategoriesRow).CategoryID
          End If
          ' als Vorgabe zurück
          e.NewObject = newRow
          ' durch AddNew bereits eingefügt, hier positionieren
          Me.ProductsBindingSource.Position = Me.ProductsBindingSource.Count - 1
    
        Catch ex As Exception
          MessageBox.Show(Me, ex.Message)
        End Try
      End Sub
    
    Einige Dinge die dabei zu beachten sind:

    Da gebundene Liste hier eine DataView ist, muß man die neue Zeile darüber erzeugen -
    DataTable.NewRow würde nicht funktionieren).
    Die so erzeugte Zeile muß man dem Ereignisargument NewObject zuweisen.

    Die BindingSource erkennt das einfügen (anhand eines Vergleichs der Listegröße),
    positioniert in dem Falle aber nicht neu, deswegen muß man die Position in dem Falle selbst setzen.

     

    Variante 2 wäre die DefaultValue Eigenschaft für die jeweilige DataColumn zu setzen.
    Entsprechend zum obigen Beispiel (beim Wechseln der ComboBox-Auswahl):

      Private Sub categoryFilterToolStripComboBox_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) _
        Handles categoryFilterToolStripComboBox.SelectedIndexChanged
        Dim rowView = TryCast(categoryFilterToolStripComboBox.SelectedItem, DataRowView)
        If rowView IsNot Nothing Then
          Me.ProductsBindingSource.Filter = String.Format("CategoryID = {0}", rowView("CategoryID"))
    
          ' Zum Standardwert machen
          Me.NorthwindDataSet.Products.CategoryIDColumn.DefaultValue = rowView("CategoryID")
    
        End If
      End Sub
    
    

     

    Variante drei nutzt das DataTable.TableNewRow Ereignis , hier im Formular Konstruktor eingehängt:

     

      Public Sub New()
        InitializeComponent()
    
        AddHandler Me.NorthwindDataSet.Products.TableNewRow, AddressOf ProductsDataTable_TableNewRow
      End Sub
    
      Private Sub ProductsDataTable_TableNewRow(ByVal sender As Object, ByVal e As System.Data.DataTableNewRowEventArgs)
        Dim row = DirectCast(e.Row, NorthwindDataSet.ProductsRow)
    
        row.Discontinued = False
    
        Dim rowView = TryCast(categoryFilterToolStripComboBox.SelectedItem, DataRowView)
        If rowView IsNot Nothing Then
          ' aktuelle Auswahl zuweisen
          row.CategoryID = CInt(rowView("CategoryID"))
        End If
      End Sub
    
    
    

     

    Für die Verknüpfung von Formularen (z. B. einem Detailformular) käme der Ansatz 
    zum Tragen wie bereits diskutiert in
    DataGridView parent child with .NET 4 Was ist der letzte Stand ? {VS 2010 .NET 4 VB WindowsForms ]

    Und nein, keines der Beispiele kommt nur mit IDE aus, was aber nicht die Maßgabe sein sollte.

    Gruß Elmar

    Freitag, 19. November 2010 17:47
    Beantworter