2009-07-06 4 views
1

Ich habe eine DataGridView, die an eine Liste von Objekten namens "BaseChange" gebunden ist. Die BaseChange Objekte bestehen aus 4 Eigenschaften ...Linq Query hat einen impliziten Cast-Fehler für DataGridViewRow, wenn Option strict aktiviert ist

  • Change
  • Change
  • LastChangeDate

Die Datagridview hat Spalten für alle 4 Werte sowie eine fünfte

  • ChangeDescription gemacht (eine Checkbox-Spalte namens "colIsSelected"). Es gibt kein Problem, die Liste an das Raster zu binden und die Elemente anzuzeigen.

    Das Problem ist, dass die Abfrage, die die ausgewählten Elemente im Raster erhält, mir einen impliziten Cast-Fehler gibt, wenn Option strict aktiviert ist.

    Dies ist die Abfrage ...

    Dim _changes As List(Of BaseChange) 
    
    _changes = (From _row As DataGridViewRow In dgvChanges.Rows() _ 
          Where Convert.ToBoolean(_row.Cells(NAME_COLUMN_IS_SELECTED).Value) = True _ 
          Select DirectCast(_row.DataBoundItem, BaseChange)).ToList() 
    

    ... und es produziert die richtigen Ergebnisse mit Option streng aus. Der implizite Cast-Squiggle befindet sich im Code "_row As DataGridViewRow" und die vollständige Nachricht lautet "Implizite Konvertierung von 'Object' in 'System.Windows.Forms.DataGridViewRow'".

    Wenn ich die "As DataGridViewRow" aus der Abfrage ausschließen, bekomme ich einen späten Bindungsfehler auf die _row.Cells und _row.DataBoundItem und dies auch scheitert Option strict.

    Ich brauche dies mit Option Strict aktiviert und in VB zu arbeiten. Fehle ich hier etwas? Hat jemand Vorschläge?

  • Antwort

    3
    (From _row As DataGridViewRow In dgvChanges.Rows() 
    

    Ihr Typ des _row-Objekts muss mit der einzelnen Version des Auflistungstyps übereinstimmen.

    wie in:

    'Assumes Option Strict On and Option Implicit On 
        Dim _changes = (From _row In dgvChanges.Rows() _    
          Where Convert.ToBoolean(ctype(_row,DataGridViewRow).Cells(NAME_COLUMN_IS_SELECTED).Value) = True _   
    Select DirectCast(ctype(_row,DataGridViewRow).DataBoundItem, BaseChange)).ToList() 
    

    Linq Ihre Reihen() Sammlung als IEnumerable sehen, so ist die Reihe ein Objekt. Erklärung am unteren Rand geht ausführlicher.

    Hinzugefügt:

    Hinzufügen Option Infer sollte dies vereinfachen.

    Siehe für weitere Informationen:

    What is the best way to mix VB.NET's Option Strict and the new Option Infer directives?

    und

    http://social.msdn.microsoft.com/forums/en-US/linqprojectgeneral/thread/e3ec737a-42f8-4767-a190-78390202a991/

    Erläuterung: ich einige mehr haben zu graben, warum ist es nicht einfacher. RowCollection für ein DataGridView implementiert die ältere IEnumberable-Schnittstelle, die Objekte zurückgibt, während neuere Auflistungstypen die generische IEnumerable (Of T) -Schnittstelle implementieren, die den Typ direkt zurückgibt, wodurch das Casting überflüssig wird.

    Siehe msdn für implementierte Schnittstellen.

    +0

    Das behebt das Problem, aber ich bin immer noch ein wenig verwirrt, warum die Rows() - Auflistung nicht tatsächlich als eine Sammlung von DataGridViewRow gesehen wird. Weißt du wo ich mehr Infos dazu bekommen kann? Dies ist für eine kleine Anwendung, aber ich bin besorgt über die Menge an Gießen, die in einer größeren Anwendung benötigt werden könnte. Ich musste dies nicht für andere (generische) Sammlungstypen tun, ist das etwas zu erwarten, wenn LINQ mit nicht-generischen Sammlungen verwendet wird? Ist es so groß, wie es scheint? – StingyJack

    +0

    Ich habe unten etwas Text hinzugefügt, im Grunde, Option hinzufügen Infer –

    +2

    Ich habe den Abschnitt "Erklärung" am unteren Rand hinzugefügt, der erklärt, warum die Besetzung erforderlich ist, wenn es nicht in den meisten Codebeispielen ist, die Sie sehen. –

    Verwandte Themen