Laden...

Gleiche Methode für verschiedene Eigenschaften verwenden

Erstellt von EyeTrackJack vor 4 Jahren Letzter Beitrag vor 4 Jahren 1.459 Views
E
EyeTrackJack Themenstarter:in
35 Beiträge seit 2019
vor 4 Jahren
Gleiche Methode für verschiedene Eigenschaften verwenden

Hallo, ich habe das Problem, dass ich mehrere Eigenschaften einer Klasse mit der gleichen Methode bearbeiten muss. Und ich habe bis jetzt keine Lösung gefunden, außer die Methode zu kopieren und die Eigenschaft abzuändern. Das Ganze sieht so aus

 foreach (ListBoxItem selItem in InterListBox.SelectedItems)
{
      int selIndex = InterListBox.Items.IndexOf(selItem);
      if (double.TryParse((sender as TextBox).Text, out double d))
      InterWindowList[selIndex].Top = d;                
}

Hier wird aus einer Textbox der Wert ausgelesen und auf ein Fenster angewendet, das in einer Liste gespeichert ist. Und aus Top wird auch mal Left oder was genz anderes.

Wie kann ich jetzt verschiedene Eigenschaften bearbeiten, ohne die Methode jeweils zu kopieren?

Das Problem ist, dass ich nicht weiß, wonach ich suchen soll. Ich würde mich freuen, wenn ihr mir helfen könntet. Diese Problematik habe ich immer wieder.

Grüße
Tobias

16.806 Beiträge seit 2008
vor 4 Jahren

Das Code Snippet alleine lässt sich nur bedingt generisch umsetzen.
Es ist hier nicht ersichtlich, was InterWindowList[selIndex]

Es kann gut sein, dass diese Problematik ein Folgeeffekt eines nicht korrekten Aufbaus ist.
Eine Erweiterungsmethode bringt Dir hier kaum was.

4.931 Beiträge seit 2008
vor 4 Jahren

Zum einen solltest du den Parameter (sender as TextBox).Text (bzw. die ganze Zeile) aus der Schleife herausziehen und zum anderen hast du quasi (unnötigerweise) eine doppelte Schleife erzeugt (durch das IndexOf) - durchlaufe das ganze Array und frage auf IsSelected ab.

Dein Problem bzgl. unterschiedlicher Eigenschaften könntest du entweder mittels Reflection lösen oder aber mittels eines Delegates.

Hier mittels eines Delegates (Action<...>):


// WindowListType mußt du entsprechend setzen (es muß eine Klasse sein!)
void SetValue(string sText, Action<WindowListType, int index, double d> onSet) // todo: besseren Methodennamen finden
{
    if (double.TryParse(sText, out double d))
    {
        foreach (ListBoxItem item in InterListBox.Items)
        {
            if (item.IsSelected)
            {
                onSet?.Invoke(InterWindowList, selIndex, d);
                break;
            }
        }
    }
}

// mit Aufruf
SetValue((sender as TextBox).Text, (list, idx, d) => list[idx].Top = d); // hier kannst du auch andere Eigenschaften benutzen

(bzw. noch besser wäre es zwei Methoden zu haben, so daß auch die erste Zeile herausgezogen wird und nur der Parameter d übergeben wird bzw. sogar generisch zu machen!)

Ich persönlich würde die Methode sogar soweit generisch machen, daß sie static ist und alle Variablen als Methodenparameter übergeben werden (also auch InterListBox.Items sowie InterWindowList),

E
EyeTrackJack Themenstarter:in
35 Beiträge seit 2019
vor 4 Jahren

Super Antwort, TH69. Jetzt weiß ich, in welche Richtung ich weitersuchen muss. Vielen Dank.

E
EyeTrackJack Themenstarter:in
35 Beiträge seit 2019
vor 4 Jahren

Ich habe es jetzt mal getestet und es funktioniert, wobei ich auf Invoke verzichtet habe. Glaube nicht, dass es nötig wird, es von anderen Threads aus aufzurufen. Oder gibt es einen Grund, es mit Invoke zu machen?

Aus Foreach habe ich ein For gemacht, da ich sonst nicht an den Index komme.

Wie dem auch sei, ich habe mal wieder was dazugelernt!

4.931 Beiträge seit 2008
vor 4 Jahren

Hier geht es nicht um die Control.Invoke-Methode, sondern um die Invoke-Methode für die Delegate-Klasse:

Hinweis

The common language runtime provides an Invoke method for each delegate type, with the same signature as the delegate. You do not have to call this method explicitly from C#, Visual Basic, or Visual C++, because the compilers call it automatically. The Invoke method is useful in reflection when you want to find the signature of the delegate type. (extra auf englisch, da die deutsche [maschinelle] Übersetzung mal wieder gruselig ist)

Ich habe extra den ?.-Operator verwendet, um bei Übergabe von null keine Exception auszulösen - und dafür benötigt man einen Methodennamen (onSet?.(InterWindowList, selIndex, d) funktioniert syntaktisch nicht).