Gå til innhold

C#: problem med Forms Designer og SetBounds()


Anbefalte innlegg

SE POST 15

Hvordan får jeg til dette?

dette er ca. det jeg er ute etter, men begge vinduene skal kjøre samtidig. Og ja, jeg er temmelig fersk innen C#.

using System;
using System.Windows.Forms;

public class MainClass {
public static void Main() {
 Application.Run(new Form1());
 Application.Run(new Form2());
}
}

public class Form1 : Form {
public Form1() {
 this.Text = "Form 1";
}
}

public class Form2 : Form {
public Form2() {
 this.Text = "Form 2";
}
}

Kanskje noen småfeil i koden, men dere skjønner poenget. Nå kjøres da ikke Form2 før du har lukket Form1, men er det en måte å forhindre dette på?

 

En ting til, et litt annet tema:

using System;
using System.Drawing;
using System.Windows.Forms;

public class MainClass {
public static void Main() {
Application.Run(new Form1());
}
}

public class Form1 : Form {
public Form1() {
Button MyButton = new Button();
MyButton.Text = "abc";
MyButton.Click += new EventHandler(MyEventHandlerClass.MyButtonClick);
}
}
public class EventHandlerClass {
public void MyButtonClick(object Sender, EventArgs args) {
Form1.MyButton.Text = "def";
}
}

Koden er korta ned, og funker ikke, men illustrerer forhåpentligvis poenget mitt. Hvordan kan jeg her få denne eventen til å forandre teksten på knappen?

 

Har forresten ikke mulighet til å teste koden, sitter i Linux for øyeblikket.

Endret av hockey500
Lenke til kommentar
Videoannonse
Annonse

En løsning på spørsmål 1 kan være slik:

 

static void Main()
{
  Form1 f1 = new Form1();
  Form2 f2 = new Form2();
  f1.Show();
  f2.Show();
  Application.Run();
}

 

Når du gjør det på denne måte må du også avslutte programmet med Application.ExitThread();

 

En løsning på spørsmål 2 kan være slik (synes du gjorde dette på en litt merkelig måte, men la gå):

        
public Form2()
{
  InitializeComponent();
  Button b = new Button();
  b.Name = "knapp";
  b.Text = "Knut";
  b.Click += new EventHandler(b_Click);
  Controls.Add(b);
}

void b_Click(object sender, EventArgs e)
{
  Button b = (Button)Controls["knapp"];
  b.Text = "jens";
}

 

Øyvind

Lenke til kommentar

Det heter Casting.

 

Han kunne også skrevet det som:

Button b = this.Controls["knapp"] as Button;

 

this.Controls er listen over alle kontroller formen din har. Siden kontrollene kan være TextBox, Label, Checkbox osv så må du eksplisitt fortelle at programmet skal se "knapp" som en Button når du vil la b referere til denne.

Lenke til kommentar
hva var merkelig med det? det er den måten det er gjort på i boka mi, C# Bible, hvertfall.

 

Det som er "merkelig" er jo problemet ditt: hvordan få tak i knappen fra en annen metode. Det som er vanlig (og blir gjort når du visuelt legger på en knapp på en form) er at knappen deklareres på klasse-nivå og ikke metode-nivå.

 

Øyvind

Lenke til kommentar

Ja, knapper og event handlers deklareres på klassenivå. Det har jeg gjort i denne koden:

using System;
using System.Windows.Forms;
using System.Drawing;

class WrapperClass
{

public class MainClass {
 public static void Main() {
 	Form1 f1 = new Form1();
 	Form2 f2 = new Form2();
 	f1.Show();
 	f2.Show();
 	Application.Run();
 }
}
public class Form1 : Form {
 Button b;
 
 public Form1() {
 	this.Text = "Heisann fra Form1";
 	
 	this.b = new Button();
 	b.Location = new Point(10,10);
 	b.Text = "Knapp";
 	b.Height = 50;
 	b.Width = 250;
 	b.Click += new EventHandler(bClick);
 	Controls.Add(b);
 }
 public void bClick(object Sender, EventArgs args) {
 	b.Text = "Du klikket her.\n Skjedde det noe med labelen på Form2?";
 	
 	Form2 f2 = new Form2();
 	f2.bClicked();
 }
}
public class Form2 : Form {
 public Label l;
 public Form2() {
 	this.Text = "Heisann fra Form2";
 	
 	this.l = new Label();
 	l.Location = new Point(10,10);
 	l.Width = 100;
 	l.Height = 100;
 	l.Text = "Dette er en label";
 	Controls.Add(l);
 }
 public void bClicked() {
 	l.Text = "Du klikket på knappen";
 }
}
}

Syns du denne koden var bedre? btw, dere C# guruer ser sikkert at det jeg har prøvd å gjøre med å kalle metoden bClicked i Form2 fra bClick i Form1 ikke funker. Hvordan kan jeg gjøre dette? kanskje jeg er litt treig nå, men jeg skjønner det ikke :dontgetit:

Lenke til kommentar

Vel Form2 som du åpnet opp Main() er ikke den samme som den nye du oppretter i Form1.bClick().

 

Skal du endre må du referere til den originale Form2'en din.

Enten ved å sende inn referanse til form1 i starten eller ved å gjøre f2 public static i MainClass.

 

Da tar du MainClass.f2.bClicked() istedet.

Lenke til kommentar

using System;
using System.Windows.Forms;
using System.Drawing;

class WrapperClass
{
public class MainClass {

public static  Form1 f1 = new Form1();
public static  Form2 f2 = new Form2();

public static void Main() {
 f1.Show();
 f2.Show();
 Application.Run();
}
}
public class Form1 : Form {
Button b;

public Form1() {
 this.Text = "Heisann fra Form1";
 
 this.b = new Button();
 b.Location = new Point(10,10);
 b.Text = "Knapp";
 b.Height = 50;
 b.Width = 250;
 b.Click += new EventHandler(bClick);
 Controls.Add(b);
}
public void bClick(object Sender, EventArgs args) {
 b.Text = "Du klikket her.\n Skjedde det noe med labelen på Form2?";
 
//  Form2 f2 = new Form2();
 MainClass.f2.bClicked();
}
}
public class Form2 : Form {
public Label l;
public Form2() {
 this.Text = "Heisann fra Form2";
 
 this.l = new Label();
 l.Location = new Point(10,10);
 l.Width = 100;
 l.Height = 100;
 l.Text = "Dette er en label";
 Controls.Add(l);
}
public void bClicked() {
 l.Text = "Du klikket på knappen";
}
}
}

 

 

kjører du "new" på en klasse/form så oppretter du en helt ny instans av den og ikke den samme du lagde først. Dette er tross alt bare klasser.

Endret av wolf5
Lenke til kommentar

Statisk betyr at det kun finnes 1 av den, uansett hvor mange instanser du lager av klassen den er i eller overliggende klasser. Du kan bruke statiske variabler til å holde felles variabler på tvers av ørten instanser av samme klasse.

 

Full sti til vil sikkert være

WrapperClass.MainClass.f2.bClicked();

Lenke til kommentar

litt OT, men spør allikavel:

 

1: Er det mulig å lage en global KeyEvent, uansett hvilken control som har fokus? slik at jeg slipper å legge til KeyEvents på absolutt alle controls på formen.

 

2: I Form Designeren ser programmet ut slik det skal, men når jeg kjører programmet enten ved å kjøre .exe fila eller ved F5 i #develop, blir alt gråere og kjedeligere. F.eks. knapper blir gråere og "flatere" i utseendet, og groupBoxes får grå tittel istedenfor den blåfargen den har i form designeren. Hvordan kan jeg få programmet til å se ut slik det gjør i form designeren?

Endret av hockey500
Lenke til kommentar

takk nok en gang! er det mulig å få form designeren til å jobbe med 2 forms? slike at jeg slipper å kode nr. 2 manuelt.

 

EDIT: fiksa det :p

 

Okei, enda et problem som jeg ikke skjønte stort av:

Jeg skal sette en form til 50 % width av GetWorkingArea(this) og height til det samme. Formen skal plasseres nederst til høyre. Jeg bruker denne koden:

SetBounds(
(Screen.GetWorkingArea(this).Width - Width),
(Screen.GetWorkingArea(this).Height - Height),
(Screen.GetWorkingArea(this).Width / 2),
(Screen.GetWorkingArea(this).Height / 2)
);

Koden kompilerer, men etter dette fungerer ikke Forms Designeren lenger :dontgetit:

System.ComponentModel.Design.Serialization.CodeDomSerializerException: 
The variable 'Screen' is either undeclared or was never assigned.
  at System.ComponentModel.Design.Serialization.CodeDomSerializerBase.
Error(IDesignerSerializationManager manager, String exceptionText, String helpLink)
  at System.ComponentModel.Design.Serialization.CodeDomSerializerBase.
DeserializeExpression(IDesignerSerializationManager manager, String name, CodeExpression expression)
  at System.ComponentModel.Design.Serialization.CodeDomSerializerBase.
DeserializeExpression(IDesignerSerializationManager manager, String name, CodeExpression expression)
  at System.ComponentModel.Design.Serialization.CodeDomSerializerBase.
DeserializeExpression(IDesignerSerializationManager manager, String name, CodeExpression expression)
  at System.ComponentModel.Design.Serialization.CodeDomSerializerBase.
DeserializeExpression(IDesignerSerializationManager manager, String name, CodeExpression expression)
  at System.ComponentModel.Design.Serialization.CodeDomSerializerBase.
DeserializeExpression(IDesignerSerializationManager manager, String name, CodeExpression expression)
  at System.ComponentModel.Design.Serialization.CodeDomSerializerBase.
DeserializeStatement(IDesignerSerializationManager manager, CodeStatement statement)

Endret av hockey500
Lenke til kommentar

Er dette kode du har plasser inn som design time kode?

I så fall betyr det at Screen objeket ikke er tilgjenglig i design time...

 

 

Ellers hadde det vært greit å visst hvor du plasserte denne koden.

 

 

Obs. Lag nye poster istedet for å endre gamle. Disse postene gir lite nytte om andre ikke kan finne svar her i fremtiden. Overskriften sier lite om inneholdet i posten nå.

En annen ting er at noen folk ser etter poster med 0 svar og ser om de kan hjelpe der, mens de ignorerer andre med flere svar.

Endret av wolf5
Lenke til kommentar

ja, plassert inn som design-time kode. Jeg plassert koden midt inni all annen MainForm kode:

        // 
 	// MainForm
 	// 
 	this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
 	this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
 	this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
 	this.BackColor = System.Drawing.SystemColors.Control;
 	//this.ClientSize = new System.Drawing.Size(671, 355);
 	this.ClientSize = new System.Drawing.Size(
                 (Screen.GetWorkingArea(this).Width / 100 * 70),
                 (Screen.GetWorkingArea(this).Height / 100 * 47));
 	this.SetBounds((0),
                 (0),
                 (Width),
                 (Height));
 	this.Controls.Add(this.groupBox5);
 	this.Controls.Add(this.groupBox4);
 	this.Controls.Add(this.groupBox3);
 	this.Controls.Add(this.groupBox2);
 	this.Controls.Add(this.groupBox1);
 	this.Controls.Add(this.label16);
 	this.Controls.Add(this.menuStrip1);
 	this.KeyPreview = true;
 	this.Name = "MainForm";
 	this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
 	this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(MainFormCancelEventHandler);
 	this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.KeyEventHandlerMethod);
 	((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).EndInit();
 	this.groupBox1.ResumeLayout(false);
 	this.groupBox2.ResumeLayout(false);
 	this.groupBox3.ResumeLayout(false);
 	this.groupBox3.PerformLayout();
 	this.groupBox4.ResumeLayout(false);
 	this.tabControl1.ResumeLayout(false);
 	this.menuStrip1.ResumeLayout(false);
 	this.menuStrip1.PerformLayout();
 	this.groupBox5.ResumeLayout(false);
 	this.ResumeLayout(false);
 	this.PerformLayout();

Endret av hockey500
Lenke til kommentar

det funket jo sånn passe hvertfall.

 

1: jeg må strekke ut igjen formen i designeren, og da legges jo this.ClientSize til igjen på MainForm

2: Designeren fjerner this.Load eventen automatisk

 

Da funker jo hvertfall designeren igjen, men jeg må manuelt endre på punkt 1 og 2 før jeg kompilerer. Er det ikke mulig å strekke ut formen i designeren uten at den rører ClientSize propertien?

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...