Benutzer mit den meisten Antworten
Eine Form mehrfach auf mehreren Monitoren aufrufen mit verschiedenen Variablen

Frage
-
Hallo,
ich bin Anfänger und hoffe ihr könnt mir helfen.
Ich habe vor folgendes zu tun:Mit C# 2013 und dem neuen .Net 4.5 eine Form erstellen und diese Form mehrfach auf mehreren Bildschirmen anzeigen.
Zum Anzeigen habe ich eine Funktion in die Form gesetzt die so aussieht:
private void showOnMonitor(int showOnMonitor)
{
Screen[] sc;
sc = Screen.AllScreens;
if (showOnMonitor >= sc.Length)
{
showOnMonitor = 0;
}
this.StartPosition = FormStartPosition.Manual;
this.Location = new Point(sc[showOnMonitor].Bounds.Left, sc[showOnMonitor].Bounds.Top);
this.WindowState = FormWindowState.Normal;
this.WindowState = FormWindowState.Maximized;
}Sofern ich jetzt in der Form showOnMonitor(x) aufrufe, zeigt er mir die Form da an wo ich sie haben will. Jetzt kommt aber der Punkt, warum ich das hier schreibe. Diese Form soll mehrfach auf mehreren Monitoren aufgerufen werden. Also aus dem Program heraus und nicht aus der Form. Und natürlich müssen die Formen voneinander unterschieden werden können.
Dafür hatte ich schon etwas gesucht und etwas die das hier gefunden (was aber so nicht funktioniert):
private void formenaufruf()
{
int formenanzahl = Screen.AllScreens.Count();
Form[] frm = new Form[formenanzahl];
for (int i = 0; i < formenanzahl; i++)
{
Thread.Sleep(3000);
frm[i] = new Form();
showOnMonitor(i);
}
}Was kann ich tun um aus dem Program heraus die Form aufzurufen und eine oder mehrere Variablen mitzugeben, die mir diese Formen dann auf die Monitore zuweist und nebenbei auch eine Zahl deklariert, anhand derer ich später die Form mit verschiedenen Konfigurationen füllen kann (die Funktionen sind überall die gleichen)?
Kann ich in "Application.Run(new frm_regal());" eine Variable mitgeben die dann im frm_regal_Load() etwas spezielles tut?
Oder hat jemand eine Idee wie ich hier vorgehen könnte? (Also außer 256 Formkopien zu erstellen und dann bei Bedarf aufzurufen... ;) )
- Bearbeitet Marcel Gpunkt Freitag, 20. Juni 2014 08:58
Antworten
-
Hallo,
stelle dir eine Klasse wie ein Ausfüllformular vor. Du hast somit die Vorlage "Form". In diesem Formular kannst du Felder wie "Title" und "Controls" mit eigenen Werten belegen.Du hast in deinem Projekt eine Klasse frm_regal. Diese stellt ein eigenständiges Fenster dar.
In der Program.cs wird diese Form aufgerufen und somit angezeigt. Da du mehrere Formen anzeigen willst (so zu sagen mehrere Ausfüllformular ausdrucken), musst du die Startroutine anpassen://using System; //using System.Collections.ObjectModel; //using System.Windows.Forms; [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); openedForms = new ObservableCollection<Form>(); openedForms.CollectionChanged += openedForms_CollectionChanged; foreach (var screen in Screen.AllScreens)//Alle Bildschirme durchlaufen { var frm = new frm_regal(screen);//Neue Forminstanz anlegen und Screen-Objekt übergeben //Nachfolgend: Die Größe des Monitors (abzüglich der Taskleiste) an die neue Form weiter geben frm.Show(); frm.Left = screen.WorkingArea.Left; frm.Top = screen.WorkingArea.Top; frm.Width = screen.WorkingArea.Width; frm.Height = screen.WorkingArea.Height; frm.WindowState = FormWindowState.Maximized;//Fenster maximieren frm.FormClosed += frm_Closde; openedForms.Add(frm);//Die neue Form mit abspeichern } Application.Run();//Hält die Anwendung offen } static void openedForms_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { //Anwendung beenden, wenn keine Form mehr geöffnet ist if (openedForms.Count == 0) Application.Exit(); } static ObservableCollection<Form> openedForms;//Speichert die geöffneten Forms private static void frm_Closde(object sender, FormClosedEventArgs e) { openedForms.Remove(sender as Form);//geschlossene Form aus Liste entfernen for (int i = openedForms.Count - 1; i >= 0; --i)//Alle Formen durchgehen und ordentlich schließen { openedForms[i].FormClosed -= frm_Closde;//Dauerschleife verhindern openedForms[i].FormClosed += (s2, e2) => openedForms.Remove(s2 as Form);//Form entfernen, wenn sie geschlossen wurde openedForms[i].Close();//Form schließen } }
Das sieht erstmal etwas kompliziert aus, ist aber eigentlich einfach.
in der Klasse frm_regal habe ich nun noch den Konstruktor angepasst:
public frm_regal(Screen scr) { InitializeComponent(); this.Screen = scr; } internal Screen Screen { get; set; }
Wozu du das Screen-Objekt in der Kalsse brauchst, weiß ich nicht. So kannst du es aber übergeben.
Tom Lambert - C# MVP
Bitte bewertet- und markiert Beiträge als Antwort. Danke.
Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter
Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets- Als Antwort markiert Marcel Gpunkt Dienstag, 24. Juni 2014 06:42
Alle Antworten
-
Hallo Taldrit,
wenn Du der Form eine oder mehrere Variable(n) übergeben willst, benötigst Du entsprechende Konstruktoren.
Bsp. Konstruktor mit Listboxvariable und 3 stringvariablen:
public frm_regal( ListBox lb, string Info, string Formtext, string Quellbezeichnung ) { //Dein Code...; }
...Du kannst soviele Konstruktoren, mit unterschiedlichen Parametern übergeben, wie Du brauchst. Der Aufruf muss dann entsprechend erfolgen...
- Bearbeitet Ralf A Freitag, 20. Juni 2014 12:41
-
Aus der Hütte geschossen:
Mach deine showOnMonitor-Methode public, erzeuge in deinem Programm mehrere Instanzen deiner Form, und zeige sie durch Aufrufen der showOnMonitor mit Übergabe der Monitor-Id dort an, wo sie erscheinen soll.
Andreas Richter
Softwareentwickler und -architekt
http://www.anrichter.net -
Hallo,
so wie ich dich verstanden habe, weißt du nicht wie du die Formen mit den Monitoren zuordnen sollst. (Das du weißt welche Form-Instanz auf welchem Monitor liegt). Das brauchst du zum späteren Übergeben von Daten.Momentan scheinst du nur ein Array von Form-Instanzen zu verwalten. Ich empfehle dir eine Klasse davona bzuleiten, die einen Ferweis auf den Screen enthält:
public class ScreenForm:Form { public ScreenForm(Screen screen):base(){ this.Screen=screen; } public Screen Screen{get;set;} }
Deine weiteren Formen, die du anzeigen möchtest, leitest du nun von ScreenForm ab. So kannst du beim Instanzieren den Beildschirm mit angeben. Durch die Screen-Eigenschaft bekomsmt du später heraus, wo die Form ursprünglich Platziert wurde. (Der Benutzer kann diese Standardmäßig immernoch verschieben.)
Statt der Screen-Instanz kannst du natürlich auch den Index o.ä. abspeichern.
PS: Beim anlegen der Form musst du showOnMonitor von der neuen Form aufrufen:
frm[i].showOnMonitor(i);
Die Methode muss dafür natürlich public sein.
Tom Lambert - C# MVP
Bitte bewertet- und markiert Beiträge als Antwort. Danke.
Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter
Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets -
Ok, ich hab jetzt über nen halben Tag rumgetüftelt, aber trotz intensiver Suche und Nachlesens fehlen mir wohl einfach noch Grundkenntnisse um mit diesen Antworten arbeiten zu können.
Das mit den Konstruktoren war einfach nachzuvollziehen und mir schon fast peinlich, weil ich immer nur aufs frm_regal_Load() geachtet habe, statt auf frm_regal()...
Wenn ich aber eine Form mehrfach aufrufen will muss ich diese ja als mehrfach vorhandenes Objekt erstellen, korrekt? Also setzt ich ins Main() einfach meine Schleife mit dem Aufruf. ABER... wie erzeuge ich diese frm_regal-Unterklassen? Mit der Angabe der Children komm ich so nicht weiter, sorry.
frm[i] = new ScreenForm(i) führt zu Fehlern ebenso wie ...new Form(i), etc. bekomme immer wieder andere Fehlermeldungen. Wie mache ich das richtig?
Wenn ich die ScreenForm von Form ableite, wie definiere ich diese dann als Teil von frm_regal? Muss ich den public class ScreenForm:Form erzeuge, muss ich den dann ins Program oder in die frm_regal.cs setzen?
Ich fühle mich gerade mehr als dumm, aber dieser komplette Objektorientierte Programmierkram ist mir immer noch fremd... auch wenn ich mich schon bemühe das zu verstehen.
- Bearbeitet Marcel Gpunkt Montag, 23. Juni 2014 12:57
-
Hallo,
stelle dir eine Klasse wie ein Ausfüllformular vor. Du hast somit die Vorlage "Form". In diesem Formular kannst du Felder wie "Title" und "Controls" mit eigenen Werten belegen.Du hast in deinem Projekt eine Klasse frm_regal. Diese stellt ein eigenständiges Fenster dar.
In der Program.cs wird diese Form aufgerufen und somit angezeigt. Da du mehrere Formen anzeigen willst (so zu sagen mehrere Ausfüllformular ausdrucken), musst du die Startroutine anpassen://using System; //using System.Collections.ObjectModel; //using System.Windows.Forms; [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); openedForms = new ObservableCollection<Form>(); openedForms.CollectionChanged += openedForms_CollectionChanged; foreach (var screen in Screen.AllScreens)//Alle Bildschirme durchlaufen { var frm = new frm_regal(screen);//Neue Forminstanz anlegen und Screen-Objekt übergeben //Nachfolgend: Die Größe des Monitors (abzüglich der Taskleiste) an die neue Form weiter geben frm.Show(); frm.Left = screen.WorkingArea.Left; frm.Top = screen.WorkingArea.Top; frm.Width = screen.WorkingArea.Width; frm.Height = screen.WorkingArea.Height; frm.WindowState = FormWindowState.Maximized;//Fenster maximieren frm.FormClosed += frm_Closde; openedForms.Add(frm);//Die neue Form mit abspeichern } Application.Run();//Hält die Anwendung offen } static void openedForms_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { //Anwendung beenden, wenn keine Form mehr geöffnet ist if (openedForms.Count == 0) Application.Exit(); } static ObservableCollection<Form> openedForms;//Speichert die geöffneten Forms private static void frm_Closde(object sender, FormClosedEventArgs e) { openedForms.Remove(sender as Form);//geschlossene Form aus Liste entfernen for (int i = openedForms.Count - 1; i >= 0; --i)//Alle Formen durchgehen und ordentlich schließen { openedForms[i].FormClosed -= frm_Closde;//Dauerschleife verhindern openedForms[i].FormClosed += (s2, e2) => openedForms.Remove(s2 as Form);//Form entfernen, wenn sie geschlossen wurde openedForms[i].Close();//Form schließen } }
Das sieht erstmal etwas kompliziert aus, ist aber eigentlich einfach.
in der Klasse frm_regal habe ich nun noch den Konstruktor angepasst:
public frm_regal(Screen scr) { InitializeComponent(); this.Screen = scr; } internal Screen Screen { get; set; }
Wozu du das Screen-Objekt in der Kalsse brauchst, weiß ich nicht. So kannst du es aber übergeben.
Tom Lambert - C# MVP
Bitte bewertet- und markiert Beiträge als Antwort. Danke.
Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter
Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets- Als Antwort markiert Marcel Gpunkt Dienstag, 24. Juni 2014 06:42
-
Ok, das war jetzt VIEL mehr als ich brauchte. Das Screenobjekt muss ich nciht komplett übergeben, nur eine Nummer die die Nummer des Screens markiert, damit ich diesen einem bestimmten Montior zuweisen kann. Daher habe ich das dann um einiges auf folgendes verkürzt:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
int i = 0;
foreach (Screen screen in Screen.AllScreens)
{
i++;
Form frm = new frm_regal(screen, i);
frm.Show();
}
Application.Run();
}Und ich denke, selbst das hätte ich noch verkürzen können um die screen-Sache. Aber stören tuts auch nicht :)
Das war wirklich für Idioten erklärt, also genau richtig für mich, danke :D
Es gab aber noch einige Fehler mit der Übergabe der Objekte, etc. Aber egal, brauch es ja zum Glück nicht. Bin jetzt aber glücklich und kann endlich mit der Funktionalität weitermachen. Ich hoffe sowas mit Objektverschachtelung, etc. kommt nicht mehr vor... ;)