MS-Blog

Datagridview – Properties von Unterobjekten anzeigen.

Samstag, 13. Juni 2009 von Marco

Das Datagridview hat einen ganz entscheidenen Nachteil.

Man kann keine Daten von Unterobjekten anzeigen.

Es gibt einige Lösungsansätze:

http://www.developer-corner.com/Resources/KnowledgeBase/tabid/118/articleType/ArticleView/articleId/28/Default.aspx

http://blogs.msdn.com/msdnts/archive/2007/01/19/how-to-bind-a-datagridview-column-to-a-second-level-property-of-a-data-source.aspx

Ich habe mich für die erste Variante entschieden sie aber leicht abgeändert.

Als erstet erstellen wir eine eigene DataGridViewKlasse und leiten von DataGridView ab.

Public Class MyDataGridView
    Inherits Forms.DataGridView
End Class

Und dann überschreiben wir das OnCellFormat Ereigniss:

Public Class MyDataGridView
    Inherits System.Windows.Forms.DataGridView

    Protected Overrides Sub OnCellFormatting( _ 
              ByVal e As System.Windows.Forms.DataGridViewCellFormattingEventArgs)

        MyBase.OnCellFormatting(e)
        If Me.Rows(e.RowIndex).DataBoundItem IsNot Nothing _
           AndAlso Me.Columns(e.ColumnIndex).DataPropertyName.Contains(".") Then
            e.Value = BindProperty( _
                 Me.Rows(e.RowIndex).DataBoundItem, _
                 Me.Columns(e.ColumnIndex).DataPropertyName, 0)
        End If

    End Sub
End Class

Und nun müssen wir noch rekursiv das Richtige Objekt an die Zelle binden.

Public Class MyDataGridView
    Inherits System.Windows.Forms.DataGridView

    Protected Overrides Sub OnCellFormatting( _ 
              ByVal e As System.Windows.Forms.DataGridViewCellFormattingEventArgs)

        MyBase.OnCellFormatting(e)
        If Me.Rows(e.RowIndex).DataBoundItem IsNot Nothing _
           AndAlso Me.Columns(e.ColumnIndex).DataPropertyName.Contains(".") Then
            e.Value = BindProperty( _
                 Me.Rows(e.RowIndex).DataBoundItem, _
                 Me.Columns(e.ColumnIndex).DataPropertyName, 0)
        End If

    End Sub

    Private Function BindProperty(ByVal dataItem As Object, _
            ByVal bindingPath As String, ByVal index As Integer) As Object

        Dim tokens = bindingPath.Split(New Char() {CChar(".")})
        Dim token = tokens(index)

        Dim t = dataItem.GetType()
        Dim pi = t.GetProperty(token)
        Dim nextDataItem As Object

        If (pi IsNot Nothing) Then

            nextDataItem = pi.GetValue(dataItem, Nothing)

            If (index = tokens.Length - 1) Then

                Return nextDataItem
            End If

            Return BindProperty(nextDataItem, bindingPath, index + 1)
        End If

        Return Nothing

    End Function
End Class

So nun kann man im Designer dem Datagridview ungebundene Felder hinzufügen und dann bei DataProperty die Eigenschaft angeben:

Adresse.Strasse

Und das MyDataGridView löst das auf. Da wir das Feld an das Objekt gebunden haben lassen sich auf änderungen am Wert durchführen.

Man muss beim speichern einfach beachten das die Unterobjekte dann mit gespeichert werden müssen.

Gruss Marco

BindingListView

Montag, 13. April 2009 von Marco

So

Es hat mir einfach keine Ruhe gelassen. Ich habe nun eine BindingListView die, die IBindingListView implementiert geschrieben.

Mit dieser ist das einfache Sortieren und auch das Filtern möglich. Beim verändern der Daten werden immer die Orginaldaten verändert und die gefilterte Liste neu aufgebaut.

Der Filter kann im Moment erst OR Verknüpfungen verarbeiten die mit Komma getrennt sind :

Vorname=Marco,Nachname=Müller

Es werden also nun alle Marco und alle Müller angezeigt.

Das erweiterte Sortieren ist nicht möglich.

BindingListView.vb

Gruss Marco

SortableBindingList

Sonntag, 12. April 2009 von Marco

Also nach ein wenig ausprobieren bin ich auf follgendes Problem gestossen.

Wenn ich eine Datagridview eine BindingList als Datasource zuweise, kann ich diese nicht sortieren oder Filtern.

Nun da ich doch gerne eine Sortiermöglichkeit hätte habe ich diese mal im plementiert.

Die Filtermöglichkeit habe ich noch nicht implementiert.

Da ich ein verändern, löschen und hinzufügen der Daten in der Liste ermöglichen will und nicht jedesmal die Liste neu laden will wenn sich der Filter verändert.

Dafür müsse ich eine WrapperKlasse schreiben die alle Funktionen implementiert.

SortableBindingList.vb

Es gibt unter SF ein Projekt das zum Ziel hat eine BindingListe zu erstellen die das IBindingListView Interface implementiert.

Damit ist sortieren und auch filtern möglich. Soweit ich gesehen habe ist aber ein hinzufügen von Elementen zur Orgnialliste nicht möglich.

http://blw.sourceforge.net/

WCF Dienst ohne Adminrechte Hosten

Dienstag, 31. März 2009 von Marco

Falls man einen WCF Dienst unter Vista ohne Adminrechte hosten will muss man dies bei Vista anmelden:

netsh http add urlacl url=http://+:80/MyUri user=DOMAINuser

Gruss Marco

SCSF: EntityMapperTranslator Fehler im VB Code

Dienstag, 31. März 2009 von Marco

So heute habe ich ein weinig mit der Smart Client Software Factory gearbeitet.

Als ich nun einen EntityMapperTranslator erstellen wollte hat noch alles geklappt nur leider wollte er diesen nicht finden als ich Ihn aufgerufen habe.
Ein Eintrag im Forum gab dann aufschluss über das Problem:

http://www.codeplex.com/smartclient/Thread/View.aspx?ThreadId=10938

Die Basisdateien enthalten im VB Code ein paar kleine Fehler:

EntityMapperTranslator.vb

    Public MustInherit Class EntityMapperTranslator(Of TBusinessEntity, TServiceEntity)
        Inherits BaseTranslator

        Public Overloads Overrides Function CanTranslate(ByVal targetType As System.Type, ByVal sourceType As System.Type) As Boolean
			Return (targetType Is GetType(TBusinessEntity) AndAlso sourceType Is GetType(TServiceEntity)) OrElse _
			(targetType Is GetType(TServiceEntity) AndAlso sourceType Is GetType(TBusinessEntity))
		End Function

        Public Overloads Overrides Function Translate(ByVal service As [Interface].Services.IEntityTranslatorService, ByVal targetType As System.Type, ByVal source As Object) As Object
			If targetType Is GetType(TBusinessEntity) Then
				Return ServiceToBusiness(service, CType(source, TServiceEntity))
			End If

			If targetType Is GetType(TServiceEntity) Then
				Return BusinessToService(service, CType(source, TBusinessEntity))
			End If

            Throw New EntityTranslatorException()
        End Function

        Protected MustOverride Function BusinessToService(ByVal service As IEntityTranslatorService, ByVal value As TBusinessEntity) As TServiceEntity

        Protected MustOverride Function ServiceToBusiness(ByVal service As IEntityTranslatorService, ByVal value As TServiceEntity) As TBusinessEntity

    End Class

Bei VB kann man leider nicht mit dem TypeOf Operator arbeiten um diesen Vergleich auszuführen.

EntityMapperTranslaterService.vb

        Public Function CanTranslate(ByVal targetType As System.Type, ByVal sourceType As System.Type) As Boolean Implements [Interface].Services.IEntityTranslatorService.CanTranslate
            If targetType Is Nothing Then
                Throw New ArgumentNullException("targetType")
            End If
            If sourceType Is Nothing Then
                Throw New ArgumentNullException("sourceType")
            End If

			Return IsArrayConversionPossible(targetType, sourceType) OrElse FindTranslator(targetType, sourceType) IsNot Nothing
        End Function

Hier muss es isNot anstatt Is heissen.

So mal weiter üben. 🙂

Seiten

Kategorien

Suchen


RSS-Feeds

Blogroll

Meta

 

© Marco – Powered by WordPress – Design: Vlad (aka Perun)