Hallo,
Ich moechte gerne meine Daten in einem Chart auf einem zweiten Fenster
zusaetzlich anzeigen. Unten ist der Code, den ich verwende um die Daten
in den kleinen Charts anzuzeigen, alles in Form 1 und ueber den Timer
gesteuert. Nun wollte ich mit Klick auf eine Schaltflaeche ein zweites
Fenster oeffnen, was wieder so einen Chart enthaelt und die gleichen
Daten in vergroesserter Form anzeigt. Das Fenster kann ich mit einer
Schaltflaeche oeffnen, jedoch zeigt der Chart dann keinen Daten an. Ich
bekomme die Verbindung des Charts in Form2 zu den Daten von Form 1
irgendwie nicht hin. Im Anhang ist noch ein Screenshot vom Code unten.
Ich wuerde mich freuen, wenn jemand mich in die richtige Richtung
bringen koennte. Momentan will ich es ueber eine Klasse versuchen,
funktioniert aber bis jetzt noch nicht. Ich weiss nicht, ob das der
richtige Weg in meinem Fall ist.
Moin,
irgend wie ist von einer zweiten Form nichts zu sehen in deinem Code.
Du solltest ihn allerding mal überarbeiten, denn du vermischt ziemlich
wild Darstellung und Daten einsammeln.
Dein Interrupt sollte lediglich die Daten aus dem HID auslesen und eine
Struktur verpacken. Das Umwandeln und Anzeigen gehört dann in eine
andere Stelle, die benachrichtigt wird, wenn Daten eintreffen.
Das kann entweder über einen Methodenaufruf direkt erfolgen z.Bsp. als
letzte Zeile Update(neueDaten) aufrufen oder über ein Event (google
mal).
Damit löst du prinzipiell erst mal die Abhängigkeit deines "Interrupts"
von der Darstellung auf.
Dann kannst du einfach die Daten an die Form schieben, die sich dann
selber darum kümmert, sie anzuzeigen.
Grüße,
Hallo,
schau mal nach den Themen Datenmodell und PropertyChangeEvent bzw. MVVM.
Beide Formulare auf dem Model registrieren also den PropertyChangeEvent
abonnieren und gut ist.
Alles andere geht von alleine.
Gruß
Frank
Vielen Dank schon mal fuer die Hinweise. Ich habe es noch nicht
hinbekommen, aber taste mich langsam vorwaerts. Mittlerweile ist auch
mein ertstes Buch ueber C# eingetroffen.
Hier ist der Code mit dem ich das zweite Fenster erzeuge:
In der Textbox kann ich einmalig beim Aufrufen einen Wert vorfinden, das
wars dann aber.
Ich denke ich muss das Program dahingehen umbauen, dass ich die Werte
mit einem Timer aus dem Buffer hole, dann die Werte global verfuegbar
mache und dann mit einem zweiten Timer die Werte in den Diagrammen
anzeige.
Mark W. schrieb:> Vielen Dank schon mal fuer die Hinweise. Ich habe es noch nicht> hinbekommen, aber taste mich langsam vorwaerts. Mittlerweile ist auch> mein ertstes Buch ueber C# eingetroffen.
Enthält das Buch auch ein Kapitel über SW Architektur und Design
Pattern?
Peter schrieb:> Mark W. schrieb:>> Vielen Dank schon mal fuer die Hinweise. Ich habe es noch nicht>> hinbekommen, aber taste mich langsam vorwaerts. Mittlerweile ist auch>> mein ertstes Buch ueber C# eingetroffen.>> Enthält das Buch auch ein Kapitel über SW Architektur und Design> Pattern?
Titel ist Visual Studio C# Programming and PC interfacing von John
Allwork
Du schreibst, dass du in Form2.ChartX die selben Daten anzeigen
möchtest, wie in Form1.ChartX.
Was mir als Info fehlt ist, ob die Daten in Form2.ChartX live, also
während einer Messung, angezeigt werden sollen oder nur diejenigen, die
zum Zeitpunkt der Anzeige von Form2.ChartX vorhanden sind?
Im ersten Fall reicht es, eine Kopie der Daten an Form2 mitzugebeben.
Stuzig macht mich aber die button1_Click(object sender, EventArgs e)
Methode:
form2Show.setChart1(ADCCH1mvolts);
...
form2Show.Show();
Hier setzt du einen double Wert, den das Chart anzeigen soll, richtig?
Der Code wird genau einmal durchlaufen. Und zwar dann, wenn das
entsprechende Event ausgelöst wird ('Button wurde gedrückt'). Also wird
auch das Chart nur diesen einen Wert anzeigen. Dto. gilt für die
Textbox.
Im zweiten Fall (live Daten) müßte sich deine Form2.ChartX-Klassse als
Listener bei deiner Datendevice-Klasse anmelden.
Eins noch am Rande:
Mir ist aufgefallen, dass du in der InputTimer_Tick(object sender,
EventArgs e) Methode weder auf sender, noch auf die EventArgs zugreifst.
Statt dessen greifst du auf eine Instanz von myHidDevice zu.
Gibt es einen Grund dafür?
Das ist in soweit ungewöhnlich, als dass ich hier erwartet hätte, dass
die neuen Messdaten entweder in den EventArgs enthalten sind, ober aber
das sender eine Referenz auf den Erzeuger der Daten ist.
Wer ist hier der sender und was steht in den EventArgs?
Hi. Füge deinem Programm ein Dataset hinzu. Im Designer kannst Du die
gewünschten Tabellen für Daten erstellen. Per timer oder event oder wie
auch immer befüllst du das dataset. Per databinding zeigst du die
gewünschten daten im gewünschten Fenster an.
Vorteil: Die daten lassen sich mit einer Zeile code als datei speichern
und laden. Durch den designer werden alle erfordelichen Funktionen im
Programm erstellt.
Alle erfordelichen infos gibt es hier:
http://www.vb-paradise.de/index.php/Thread/94955-die-vier-Views-auf-Video/
(ja.. Das forum heißt so.. Aber alles dort gilt auch für c#).
Gruss
Ich habe jetzt probiert, eine Klasse als globale Variable zu verwenden,
funktioniert aber nicht. Kompiliert zwar ohne Fehler, aber im Fenster 2
werden keine Daten angezeigt.
Den code von Fenster 1 habe ich dahingehend geaendert, dass ich jetzt
die Daten in eine angelegte Klasse zusaetzlich schreibe, von der ich
hoffte, dass Fenster 2 davon lesen kann:
Und der Code fuer Fenster 2 sieht so aus. Wird auch aufgemacht, chart
bleibt aber leer. Siehe Anhang. Im Fenster 1 dagegen werden die Daten
richtig angezeigt, wie weiter oben zu sehen.
Ja, die Daten kommen live von der USB Schnittstelle, Haeufigkeit je nach
Einstellung des InputTimers in Fenster1, maximal jedoch jede 1ms.
Spaeter wollte ich das noch aendern, so dass man das im Programm
einstellen kann.
Ich denke du willst auf die Daten deiner Form1 zugreifen. Ist ja in dem
Fall eine Klasse. Um aus der Form2 heraus auf deine Form1 zugreifen zu
können, musst du eine "Verbindung" zwischen den Forms aufbauen.
D.h. public Form2() wird zu -> public Form2(Form1 MainForm)...
über dieser Zeile platzierst du nochmal ein Form1 myNewForm.... diesen
initiierst du wiederum unter deiner Zeile InitializeComponent()...
namespace Voltagelogger
{
Form1 myNewForm;
public partial class Form2 : Form
{
public Form2(Form1 MainForm)
{
myNewForm = this.MainForm;
InitializeComponent();
}
in deiner Funktion button1_Click musst du noch deine Form1 mitübergeben
also so:
form2Show.Show(this);
dann sollte es funktionieren aminakoyim
Lieber Mark, liest du nur oder verstehst du auch?
Leider hast du bisher keinen der Vorschläge berücksichtigt oder bist auf
Vorschläge eingegangen.
Dein Code zeugt eher von einem Mangel an Grundverständnis bezüglich
bestimmter Programmierparadigmen. Und nun kannst du entweder
verwurschteln und es irgendwie hinbekommen und hoffentlich das Ergebnis
nie an einen Kunden verkaufen oder aber du gehst mal einen Schritt
zurück, liest ein paar der Vorschläge hier und fragst ggf. nach.
Natürlich könntest du dir auch jemanden suchen, der sich mit dem
Handwerk des Programmierens auskennt und dir gegen Bares was Wahres
liefert.
Ich programmiere mit C# gerade erstmal 2 Wochen und es ist nur Hobby.
Bei dem Programm hab ich mich Schritt fuer Schritt von einem bestehendem
Programm vorgetastet. Nun bin ich an die Grenzen gestossen und werde
mich erstmal mit den Grundlagen auseinandersetzen. Einiges im
Programmaufbau von C# ist mir noch nicht so klar. Derzeit habe ich das
Programm ertmal umgebaut und alles in ein Fenster gelegt, nun sind alle
8 Kanaele in einem Chart sichtbar, das geht auch erstmal so.
Die Problematik jeden Kanal, der Uebersicht halber, in einem extra
Fenster anzeigen zu lassen, zusaetzlich zu den kleinen Vorschaufenstern,
habe ich erstmal ausgegliedert. Wenn ich mein Ziel erreiche, will ich es
auch verstanden haben. Ich habe mir dazu ein Minimal Programm
geschrieben und will damit erstmal nur die Sache mit dem zweiten Fenster
machen. Wenn ich Erfolge oder Fragen diesbezueglich habe, dann lass ich
es Euch wissen.
Moin... Hab dir den link auf die videos gepostet... Wenn du sowas machst
dann mach es doch gleich richtig... Ohne gewuschtel per
handgeschriebener Klassen sondern gleich objektorientiert...
Hallo Wolfgang,
habe mir den link angesehen und abgespeichert. Ich galube nicht, dass
ich jetzt schon so eine komplexe Loesung mit Datenbanken machen will.
Ich schaue mir die Videos mal bei Gelegenheit an, scheint mir aber
Overkill zu sein fuer meine Anwendung.
Hallo Mark!
In den Videos geht es eben genau nicht um Datenbanken. Es geht um
LocalDB. Darum dass Du deine Gesammelten Werte vernünftig in eine Liste
eintragen, filtern usw. kannst. Dass das ganze per Designer gemacht
werden kann nur durch erstellung entsprechender Tabellen und vor allem
dass alles Objektorientiert gehandhabt wird.
So wie dort erklärt wird ist es z. b. schlecht mit Strings als
Übergabeparameter zu arbeiten, da diese erstens geparst werden müssen
und zweiten Fehler passieren können. Per LocalDB wird der
objektorientierte Ansatz inklusive Intelisense ermöglicht. Es ist dann
nur mehr notwendig das Databinding zu setzen und die gwünschten Daten
anzeigen zu lassen.
Und nicht vom Namen des Forums abschrecken lassen. Alles was dort gesagt
wird lässt sich genauso auch in C# machen. Es werden auch genauso C#
Fragen beantwortet sollten welche auftreten.
Kanns Dir nur empfehlen es gleich richtig zu machen und alle Vorteile
des Studios zu nutzen.
Soll natürlich nicht heissen dass meine Vorredner keine Ahnung hätten...
Gruß
Nachtrag:
hier ist zu sehen, wie ich es haben moechte. Nur eben so einfach wie ich
es im ersten Fenster habe, Daten anzeigen mit nur 3 Zeilen Code und
einfach verstaendlich.
Ich habe mir das Projekt angesehen, scheint mir etwas zu umstaendlich
fuer den Moment zu sein.
https://www.youtube.com/watch?v=g_C-L97l_XI
Wolfgang H. schrieb:> ... Wenn du sowas machst> dann mach es doch gleich richtig... Ohne gewuschtel per> handgeschriebener Klassen sondern gleich objektorientiert...
Wut?
nein!!! Aufgrund von Erfahrung wollte ich nur drauf hinweisen es gleich
so zu machen. Spart eine menge arbeit.
Hab ja geschrieben dass trotzdem alles andere wahrscheinlich nicht
verkehrt ist.
>>> Ohne gewuschtel per handgeschriebener Klassen sondern gleich>>> objektorientiert...>> Wut?> nein!!!
Meine lieben Forenfreude, vielleicht vermag ich die entstandene
Konfusion zumindest in Teilen ein wenig abzumildern. Ich will mich
kurzfassen: Der Herr John wollte sicher nur - vorausgesetzt, das in
Deutsch fürwahr unglückliche "Wut" lässt sich in diesem Kontext
tatsächlich geradeweg und ohne Umscheife mit "What" übersetzen, wie es
ein sogenanntes "urbanes Wörterbuch" vorschlägt, welches ich kürzlich im
Internetz unter einigem Einsatz aufzustöbern in der Lage war - seiner
Verwunderung ob der augenscheinlichen Diskrepanz Ausdruck verleihen,
dass Ihr, Herr Wolfgang, einerseits unumwunden als aufrechter
Fürsprecher objektorientierter Programmierung, ja, als ihr Held und
Verteidiger auftretet, was ich als Anhänger derselbigen durchaus zu
goutieren weiß, andererseits jedoch personaliter konzipierten und
niedergeschriebenen Klassen - deren Vorhandensein ja gemeinhin gerade
als eines der innigsten und leidenschaftlichsten Symbole für ebendieses
Vorgehen gilt - grob ablehnend gegenüberzustehen scheint.
Ok...
Es gibt viele wege nach rom... Mein vorschlag war einer unter vielen.
Denke mal dass das der sinn von einem forum is. Und wie geschrieben mag
die klassenlösung mit Sicherheit auch ihre vorteile haben... Je nachdem
was als ziel definiert is vermute ich mal...
Hey,
was die Vorposter mit richtiger Objektorientierung meinten ist meiner
Meinung nach folgendes - eine objektorientierte Abstraktion zur Lösung
deines Problems zu nutzen.
Folgende Idee:
Erstelle eine Klasse LogEntry. Die Klasse beinhaltet einen LogEintrag.
Idee: Konstruktor mit zwei Bytes. Float Repräsentation werden von den
beiden Bytes abgeleitet. String Repräsentation von Float.
Erstelle eine Klasse DataLogger (kein Form!), diese beinhaltet eine
Liste mit LogEntry. In dieser Liste werden die Log Einträge gespeichert.
Idee: Konstruktor bekommt "myHidDevice" übergeben.
DataLogger startet seinen eigenen BackgroundTimer, in dessen Tick er den
Wert aus "myHidDevice" liest und in seiner Liste ablegt.
In deinem "MainForm" erstellt du dann eine Instanz des DataLogger.
Diese Instanz von DataLogger enthält nun alle deine gemessenen Werte,
diese Instanz kannst du nun in deinem "HauptWindow" nutzen, oder einfach
jedem Unterfenster das die Daten verarbeiten soll mitgeben.
Wenn du nun noch DataLogger einen eigenen Event spendierst, den du
feuerst wenn du im "Tick" einen neuen Messwert gelesen hast, können alle
Konsumenten des DataLogger darüber benachrichtigt werden das ein neuer
Wert vorhanden ist. (Hollywood Prinzip)
Gruß,
Sebastian