Eine konkrete Frage zu Reflection-Anwendung

  • VB.NET
  • .NET (FX) 4.0

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von WhitePage.

    Eine konkrete Frage zu Reflection-Anwendung

    Hallo,

    ich versuche da gerade durchzusteigen, leider ist MSDN ziemlich überfüllt, ich finde nicht wirklich das, was ich brauche.

    Ich habe eine Klasse X, die einige Propertys (Objekte verschiedener Klassen) enthält. Diese Klassen sind zwar unterschiedlich, enthalten aber ihrerseits alle die gleichen Propertys (unter anderem width).

    In einem Event (Columnwidthchanged) vom Datagridview will ich automatisch diejenige Width-Property setzen, an deren Objekt die Spalte gebunden ist (über .DataPropertyName).

    Meine Idee war, ich hole mir über Reflection das Objekt, dessen zugehörige Spaltenweite im DGV verändert wurde, und greife dann auf seine Width-Property, die ich setze.

    Mit item.GetType.GetField(e.Column.DataPropertyName) komme ich auf FieldInfo von dieser Property (das Objekt). Aber wenn ich GetValue anwende, bekomme ich ein Typ Object zurück, den ich wohl erst konvertieren muss. Aber dafür fehlt mir das Wissen, wie die zugehörige Klasse ist (also der Typ).

    Habe ich irgendwo einen Denkfehler? Wie komme ich jetzt auf dieses Objekt?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „WhitePage“ ()

    WhitePage schrieb:

    und greife dann auf seine Width-Property, die ich setze


    Das habe ich vor.

    Zur Zeit habe ich das Problem, dass Dim prop = MyClass.GetType.GetField(e.Column.DataPropertyName) nichts findet, weil prop Nothing bleibt.

    EDIT:
    @EaranMaleasi
    .GetType.GetFields liefert nämlich auch ein leeres Array. Kann nicht sein, oder?

    WhitePage schrieb:

    Meine Idee war, ich hole mir über Reflection das Objekt, dessen zugehörige Spaltenweite im DGV verändert wurde, und greife dann auf seine Width-Property, die ich setze.
    Also der Plan ist, indem man im DGV die Spaltenbreite ändert, trägt man gewissermassen in alle im DGV angezeigten Objekte die Spaltenbreite des DGVs ein?

    ...nicht unexotisch...
    Nun gut, eine Width-Property ist ja (normalerweise) irgendein Zahltyp. Sofern der für alle Gleich ist, kannst du ja einfach die Convert.ToZahltyp() Funktionen nutzen.
    Ansonsten wirds ne ziemlich trickreiche Reflection wurstelei.

    ErfinderDesRades schrieb:

    ...nicht unexotisch...

    :thumbsup:

    Edit:
    @WhitePage Properties != Fields
    GetFields() liefert die alle Felder, also diese hier:
    public string AField;

    während GetPropeties() dir alle Properties liefert, also diese hier:
    public string AProp { get; set; }

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „EaranMaleasi“ ()

    ErfinderDesRades schrieb:

    Also der Plan ist, indem man im DGV die Spaltenbreite ändert, trägt man gewissermassen in alle im DGV angezeigten Objekte die Spaltenbreite des DGVs ein?


    Ne, habe es doch falsch erklärt. Es geht um Nachbau von My.Settings, weil alles in einer Datenbank gespeichert werden muss (das Projekt ist schon längst im Feld, ich erweitere es nur).
    Die Breite von jeder Spalte soll gespeichert werden, dafür gibt es Propertys, die die gleichen Namen haben, wie die Objekte, an die gebunden wird (und die haben dann Width, Visible usw).

    Man kann es natürlich in einem kilometerlangen Code einzeln machen (es gibt zig verschiedene DGVs mit zig verschiedenen Spalten), aber ich wollte es gerne automatisieren.



    Zur Zeit habe ich das Problem, dass Dim prop = MyClass.GetType.GetField(e.Column.DataPropertyName) nichts findet, weil prop Nothing bleibt.

    .GetType.GetFields liefert nämlich auch ein leeres Array. Kann nicht sein, oder?

    @EaranMaleasi
    Ich muss die richtige Property des richtigen Objekts suchen, von denen ich nur die jeweils Namen habe, sowie die übergeordnete Klasse, die diese Objekts enthält. Und die bekommt dann den Wert der aktuellen Spaltenbreite.

    Ohne Reflection funktioniert es, aber eben ellenlang.

    WhitePage schrieb:

    Die Breite von jeder Spalte soll gespeichert werden, dafür gibt es Propertys, die die gleichen Namen haben, wie die Objekte, an die gebunden wird (und die haben dann Width, Visible usw).
    Ja, DatagridViewColumn hat solche Properties.
    Aber um davon Width und Visible zu speichern braucht man kein Reflection.

    Du siehst: Ich verstehe nicht was du zu erklären versuchst, vlt. versuchstes noch einmal.

    Vor allem was nun alles du speichern willst - evtl. ist das nicht soo viel, und wäre mit paar Schleifen abgehandelt.
    Ich hab auch ein lustigen UniversalSpeicher veröffentlicht, damit kann man schon das eine oder annere Persistenz-Problem lösen.
    So, jetzt habe ich meine Property (ClassA), allerdings als PropertyInfo. Wie komme ich jetzt auf die Propertys dieser ClassA, also ClassA.Width?

    ErfinderDesRades schrieb:

    Ich hab auch ein lustigen UniversalSpeicher veröffentlicht, damit kann man schon das eine oder annere Persistenz-Problem lösen.

    Schön, aber das muss in der Kundendatenbank gespeichert werden, es ist eine Vorgabe.

    Es gibt eine XML-Datei, in der Eigenschaften aller DGVs (und nicht nur) gespeichert werden, sortiert nach Objekten, an die diese DGV gebunden sind (spaltenweise, es ist eine List(Of MyClass) und jede Spalte ist an einen Member dieser Klasse gebunden).

    EDIT:
    @EaranMaleasi
    Es ist echt zum k*tzen, dass man editieren muss, anstatt zu antworten. Das liest doch kein Mensch sonst nach ;(

    Also, ich habe folgenden Code:

    VB.NET-Quellcode

    1. Dim prop = MyXMLClass.GetType.GetProperty(e.Column.DataPropertyName) 'bekomme meine Klasse, von denen ich dann weiterhin Propertys brauche
    2. Dim v = prop.GetValue(MyClass, Nothing) 'bekomme ein Object
    3. Dim tp As Type = prop.PropertyType
    4. Dim val =CType(v, tp) 'nimmt leider nicht an, sagt tp wäre keine Class.


    D.h. ich bekomme zur Zeit kein Object, von dem ich weiterhin Propertys Width holen könnte.

    EDIT:
    Vielleicht kann der Reflectiongott @~blaze~ dann helfen...

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „WhitePage“ ()

    Ich habe jetzt zwar einen Knoten im Hirn, aber es hat funktioniert :D

    VB.NET-Quellcode

    1. Dim prop = MyClass.GetType.GetProperty(Name)
    2. Dim tp = prop.PropertyType
    3. Dim v = prop.GetValue(MyClass, Nothing)
    4. Dim w = tp.GetProperty("width")
    5. w.SetValue(v, e.Column.Width.ToString, Nothing)


    Mein Denkfehler war, dass ich dachte, ich muss v vom Object in den richtigen Datentyp konvertieren, dabei brauchte ich es nicht. Für SetValue hat es als Object gereicht.