Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Funktionsaufruf über Verschachtelte Controls
Martin-FFB
myCSharp.de - Member



Dabei seit:
Beiträge: 8
Herkunft: Bayern

Themenstarter:

Funktionsaufruf über Verschachtelte Controls

beantworten | zitieren | melden

Hi,

ich habe im Moment ein vermutlich total einfaches Problem, sehe aber gerade den Wald vor lauter Bäumen nicht...

ich habe ein Table-Layout-Panel in welchem ich 2 Reihen a 8 Spalten habe... in diesen habe ich dann jeweils ein Panel eingefügt und das Panel enthält ein Custom Form Control.

Jedes Custom Control enthält ein Bild, welches über die öffentliche Funktion "UpdateStatus()" in regelmäßigen abständen aktualisiert werden soll...

Erstellen tu ich das ganze so:

TableLayoutPanel TLP = new TableLayoutPanel();
Panel l = new Panel();
l.Controls.Add(new Light(uControl, new Size(l.Width, l.Height)));
TLP.Controls.Add(I, IDCOL - 1, IDROW);

Das Status-Update versuche ich dann so aufzurufen:

foreach (Control ELEMENT in PanelList[CurGrid].Controls)
{
                try { ELEMENT.Controls[0].Controls[0].UpdateStatus(); } catch { }
}

Da bekomme ich dann aber folgenden Fehler:
Fehler CS1061 "Control" enthält keine Definition für "UpdateStatus", und es konnte keine zugängliche UpdateStatus-Erweiterungsmethode gefunden werden, die ein erstes Argument vom Typ "Control" akzeptiert (möglicherweise fehlt eine using-Direktive oder ein Assemblyverweis)

Hier ist das Usercontrol:

public partial class Light : UserControl
{
        ConfigHelper INIFile = new ConfigHelper("config.ini");
        private DateTime Startzeit1 = new DateTime();
        private Size xSize = new Size(0, 0);

        private string IPAddress;
        private int Port;


        public Light(string INFOText, Size ControlSize)
        {
            InitializeComponent();

            IPAddress = INIFile.getValue(INFOText, "IP", false);
            Port = Convert.ToInt32(INIFile.getValue(INFOText, "RELAY", false));
            lbl_info.Text = INIFile.getValue(INFOText, "TITLE", false);

            xSize = ControlSize;
            IMG_01.Image = Properties.Resources.lichtaus;            
            chgSize(this, new EventArgs());
        }

        private void chgSize(object sender, EventArgs e)
        {
            this.Size = xSize;
            lbl_info.Location = new Point((int)((this.Width - lbl_info.Width) / 2), (int)(this.Height - 30));
        }

        public void UpdateStatus()
        {
            if (GetRelay(IPAddress, Port)){IMG_01.Image = Properties.Resources.lichtan;}else{IMG_01.Image = Properties.Resources.lichtaus;}
            IMG_01.Refresh();
        }

        private bool GetRelay(string queryIP, int queryPort)
        {
            try
            {
                WebRequest RelayRequest = WebRequest.Create("http://" + queryIP + ":80/relays.cgi"); RelayRequest.Credentials = new NetworkCredential("admin", "admin"); RelayRequest.Method = "POST";RelayRequest.ContentType = "";RelayRequest.ContentLength = 0;RelayRequest.Timeout = 1000;
                Stream RelayStream = RelayRequest.GetResponse().GetResponseStream();RelayStream.ReadTimeout = 1000;
                StreamReader Relayreader = new StreamReader(RelayStream, Encoding.UTF8);string RelayContent = Relayreader.ReadToEnd();Relayreader.Close();
                string Status = RelayContent.Substring(RelayContent.IndexOf("Status:") + 8, 18);
                switch (queryPort)
                {
                    case 1: if (Status.Substring(0, 1) == "1") { return true; } else { return false; }
                    case 2: if (Status.Substring(2, 1) == "1") { return true; } else { return false; }
                    case 3: if (Status.Substring(5, 1) == "1") { return true; } else { return false; }
                    case 4: if (Status.Substring(7, 1) == "1") { return true; } else { return false; }
                    case 5: if (Status.Substring(10, 1) == "1") { return true; } else { return false; }
                    case 6: if (Status.Substring(12, 1) == "1") { return true; } else { return false; }
                    case 7: if (Status.Substring(15, 1) == "1") { return true; } else { return false; }
                    case 8: if (Status.Substring(17, 1) == "1") { return true; } else { return false; }
                }
                return false;
            }
            catch
            {
                return false;
            }            
        }

}


Muss ich da n Interface für bauen??? Ne einfache Methode wäre mir lieber....

Ich dachte auch schon daran, das Timergesteuerte Update jeweils im Usercontrol auszuführen (was auch geht), das würde dann aber auch laufen, wenn die Gridview im Moment inaktiv ist und nicht benötigt wird....

Vielen Dank schon mal für Euer Feedback
Liebe Grüße
Martin
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Martin-FFB am .
private Nachricht | Beiträge des Benutzers
Th69
myCSharp.de - Experte

Avatar #avatar-2578.jpg


Dabei seit:
Beiträge: 4001

beantworten | zitieren | melden

Hallo und willkommen,

bitte packe deinen Code in C#-Tags, sonst wird sich keiner den Code genauer anschauen.

Tipp: [FAQ] Casten aber richtig: () / is / as
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Th69 am .
private Nachricht | Beiträge des Benutzers
Martin-FFB
myCSharp.de - Member



Dabei seit:
Beiträge: 8
Herkunft: Bayern

Themenstarter:

beantworten | zitieren | melden

Danke für den Tipp... ist geändert. Hatte die Tag-Buttons nicht im Blick...
LG
Martin
private Nachricht | Beiträge des Benutzers
MarsStein
myCSharp.de - Experte

Avatar #avatar-3191.gif


Dabei seit:
Beiträge: 3429
Herkunft: Trier -> München

beantworten | zitieren | melden

Hallo,

innerhalb der Controls-Auflistung eines übergeordneten Elements sind Deine Objekte nur als Control bekannt, und da gibt es die Methode UpdateStatus eben nicht.

Wie Th69 schon angedeutet hat, musst Du das dann auf Deinen Typen zurück casten.

Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
private Nachricht | Beiträge des Benutzers
Stefan.Haegele
myCSharp.de - Member

Avatar #avatar-3068.jpg


Dabei seit:
Beiträge: 440
Herkunft: Untermeitingen

beantworten | zitieren | melden

Zitat von Martin-FFB


                switch (queryPort)
                {
                    case 1: if (Status.Substring(0, 1) == "1") { return true; } else { return false; }
                    case 2: if (Status.Substring(2, 1) == "1") { return true; } else { return false; }
                    case 3: if (Status.Substring(5, 1) == "1") { return true; } else { return false; }
                    case 4: if (Status.Substring(7, 1) == "1") { return true; } else { return false; }
                    case 5: if (Status.Substring(10, 1) == "1") { return true; } else { return false; }
                    case 6: if (Status.Substring(12, 1) == "1") { return true; } else { return false; }
                    case 7: if (Status.Substring(15, 1) == "1") { return true; } else { return false; }
                    case 8: if (Status.Substring(17, 1) == "1") { return true; } else { return false; }
                }
}
TIPP: Geht einfacher:


                switch (queryPort)
                {
                    case 1: return(Status.Substring(0 , 1) == "1");
                    case 2: return(Status.Substring(2 , 1) == "1");
                    case 3: return(Status.Substring(5 , 1) == "1");
                    case 4: return(Status.Substring(7 , 1) == "1");
                    case 5: return(Status.Substring(10, 1) == "1");
                    case 6: return(Status.Substring(12, 1) == "1");
                    case 7: return(Status.Substring(15, 1) == "1");
                    case 8: return(Status.Substring(17, 1) == "1");
                }
}
private Nachricht | Beiträge des Benutzers
Th69
myCSharp.de - Experte

Avatar #avatar-2578.jpg


Dabei seit:
Beiträge: 4001

beantworten | zitieren | melden

Oder noch einfacher:


switch (queryPort)
{
    case 1: return Status[0] == '1';
    // ...
}
Aber statt dem switch würde ich persönlich ein Array benutzen (DRY):


int indices[] = { 0, 0, 2, 5, 7, 10, 12, 15, 17 };

if (queryPort ≥ 1 && queryPort < indices.Length)
{
    int index = indices[queryPort];
    return Status[index] == '1';
}

return false;
private Nachricht | Beiträge des Benutzers
Martin-FFB
myCSharp.de - Member



Dabei seit:
Beiträge: 8
Herkunft: Bayern

Themenstarter:

beantworten | zitieren | melden

Zitat von Th69
Hallo und willkommen,

bitte packe deinen Code in C#-Tags, sonst wird sich keiner den Code genauer anschauen.

Tipp: [FAQ] Casten aber richtig: () / is / as

Wie Geil! Kaum macht man es richtig, schon Funzts…

vielen Dank!!! Es tut nun!

            foreach (Control ELEMENT in PanelList[CurGrid].Controls)
            {
                try
                {
                    Control MyControl = ELEMENT.Controls[0].Controls[0];
                    if (MyControl is Light)
                    {
                        Light myLight = (Light)MyControl;
                        myLight.UpdateStatus();
                    }
                }
                catch { }
            }
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Martin-FFB am .
private Nachricht | Beiträge des Benutzers
Martin-FFB
myCSharp.de - Member



Dabei seit:
Beiträge: 8
Herkunft: Bayern

Themenstarter:

beantworten | zitieren | melden

Zitat von Stefan.Haegele
TIPP: Geht einfacher:


                switch (queryPort)
                {
                    case 1: return(Status.Substring(0 , 1) == "1");
                    case 2: return(Status.Substring(2 , 1) == "1");
                    case 3: return(Status.Substring(5 , 1) == "1");
                    case 4: return(Status.Substring(7 , 1) == "1");
                    case 5: return(Status.Substring(10, 1) == "1");
                    case 6: return(Status.Substring(12, 1) == "1");
                    case 7: return(Status.Substring(15, 1) == "1");
                    case 8: return(Status.Substring(17, 1) == "1");
                }
}

Stimmt. Cool Vielen Dank!
private Nachricht | Beiträge des Benutzers
Martin-FFB
myCSharp.de - Member



Dabei seit:
Beiträge: 8
Herkunft: Bayern

Themenstarter:

beantworten | zitieren | melden

Zitat von Th69
Oder noch einfacher:


switch (queryPort)
{
    case 1: return Status[0] == '1';
    // ...
}

Hm... Interessant... also quasi den String direkt über einen Index zerlegen... Hatte ich noch nicht auf dem Schirm... muss ich mir mal ansehen... Danke!
Zitat von Th69
Oder noch einfacher:
Aber statt dem switch würde ich persönlich ein Array benutzen (DRY):


int indices[] = { 0, 0, 2, 5, 7, 10, 12, 15, 17 };

if (queryPort ≥ 1 && queryPort < indices.Length)
{
    int index = indices[queryPort];
    return Status[index] == '1';
}

return false;
Weil es schneller ist? Andererseits belegt es mehr Speicher, oder?

Vielen Dank
Liebe Grüße
Martin
private Nachricht | Beiträge des Benutzers
Th69
myCSharp.de - Experte

Avatar #avatar-2578.jpg


Dabei seit:
Beiträge: 4001

beantworten | zitieren | melden

Weder noch, sondern wegen dem Stichwort Don't repeat yourself (DRY).

Es ist performancetechnisch (in etwa) gleich gut.
Bei Codeänderung (bzw. Erweiterung) braucht man nur eine Stelle (im Array) verändern, ohne jedesmal eine neue Codezeile hinzufügen (welche ja auch Speicher benötigt)!
Ich persönlich trenne in meinem Code soweit es geht Daten und Funktionalität (Methoden), so daß der Code selbst besser wiederverwendbar ist.

PS: Und die Indexabfrage, weil dies kürzer zu schreiben (und besser zu lesen) ist, als einen Substring-Aufruf von einem Zeichen zu benutzen.
private Nachricht | Beiträge des Benutzers
Martin-FFB
myCSharp.de - Member



Dabei seit:
Beiträge: 8
Herkunft: Bayern

Themenstarter:

beantworten | zitieren | melden

Zitat von Th69
Weder noch, sondern wegen dem Stichwort Don't repeat yourself (DRY).

Es ist performancetechnisch (in etwa) gleich gut.
Bei Codeänderung (bzw. Erweiterung) braucht man nur eine Stelle (im Array) verändern, ohne jedesmal eine neue Codezeile hinzufügen (welche ja auch Speicher benötigt)!
Ich persönlich trenne in meinem Code soweit es geht Daten und Funktionalität (Methoden), so daß der Code selbst besser wiederverwendbar ist.

PS: Und die Indexabfrage, weil dies kürzer zu schreiben (und besser zu lesen) ist, als einen Substring-Aufruf von einem Zeichen zu benutzen.

Prima Erklärung. Vielen Dank...
Ich werde mir das versuchen zu Herzen zu nehmen. Ist ja auch einleuchtend… Ist aber halt immer so, das man doch aus seinen alten eingefahrenen Wegen schwer rauskommt... wenn man dann eine Sprache wechselt, sucht man sich nicht die bessere Funktion sondern meist die ähnlichere und nutzt die bis zur Rente :-) Aber ich versuche daran zu arbeiten...

Vielen Dank
Liebe Grüße
Martin (noch 13 Jahre bis zur Rente...)
private Nachricht | Beiträge des Benutzers