Frage

Sorry für den Titel, es ist nicht explizit.

Weitere meines Präzedenzfall Frage , ich will eine Methode auf ein Ereignis-Objekt zeichnen dynamisch abgerufen (durch Reflexion). Das betreffende Objekt ist ein Feld einer Steuerung:

public void SubscribeEvents(Control control)
{
    Type controlType = control.GetType();
    FieldInfo[] fields = controlType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

    MethodInfo method = typeof(Trace).GetMethod("WriteTrace");

    // "button1" hardcoded for the sample
    FieldInfo f = controlType.GetField("button1", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

    // "Click" hardcoded for the sample
    EventInfo eInfo = f.FieldType.GetEvent("Click");

    if (eInfo != null)
    {
        EventHandler dummyDelegate = (s, e) => WriteTrace(s, e, eInfo.Name);
        Delegate realDelegate = Delegate.CreateDelegate(eInfo.EventHandlerType, dummyDelegate.Target, dummyDelegate.Method);
        eInfo.AddEventHandler(?????, realDelegate); // How can I reference the variable button1 ???
    }
}

Ich weiß nicht, wie die Variable verweisen ‚button1‘. Ich habe so etwas wie dies versucht:

public void SubscribeEvents(Control control)
{
    Type controlType = control.GetType();
    FieldInfo[] fields = controlType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

    MethodInfo method = typeof(Trace).GetMethod("WriteTrace");

    // "button1" hardcoded for the sample
    FieldInfo f = controlType.GetField("button1", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

    // "Click" hardcoded for the sample
    EventInfo eInfo = f.FieldType.GetEvent("Click");

    Type t = f.FieldType;
    object o = Activator.CreateInstance(t);

    f.GetValue(o);

    if (eInfo != null)
    {
        EventHandler dummyDelegate = (s, e) => WriteTrace(s, e, eInfo.Name);
        Delegate realDelegate = Delegate.CreateDelegate(eInfo.EventHandlerType, dummyDelegate.Target, dummyDelegate.Method);
        eInfo.AddEventHandler(o, realDelegate); // Why can I refer to the variable button1 ???
    }
}

Aber ich habe hier eine Ausnahme:

        f.GetValue(o);

System.ArgumentException wurde nicht behandelt   Message = Feld ‚button1‘ definiert auf Typ ‚WindowsFormsApplication1.Form1‘ ist kein Feld auf dem Zielobjekt, das vom Typ ‚System.Windows.Forms.Button‘.

War es hilfreich?

Lösung

Das ist, weil Sie versuchen, eine neue Instanz von Button zu erstellen und zu versuchen, den Wert seiner button1 Eigenschaft zu erhalten, die offensichtlich nicht existiert.

Ersetzen Sie diese:

Type t = f.FieldType;
object o = Activator.CreateInstance(t);

f.GetValue(o);

mit dieser:

object o = f.GetValue(control);

Sie können eine Methode wie diese verwenden Sie den Wert eines Feldes für jedes Objekt zu erhalten:

public static T GetFieldValue<T>(object obj, string fieldName)
{
    if (obj == null)
        throw new ArgumentNullException("obj");

    var field = obj.GetType().GetField(fieldName, BindingFlags.Public |
                                                  BindingFlags.NonPublic |
                                                  BindingFlags.Instance);

    if (field == null)
        throw new ArgumentException("fieldName", "No such field was found.");

    if (!typeof(T).IsAssignableFrom(field.FieldType))
        throw new InvalidOperationException("Field type and requested type are not compatible.");

    return (T)field.GetValue(obj);
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top