Hi,
Ich habe ein kleines Programm geschrieben das ein Koordinaten-System zeichnet und danach beliebige Graphen darauf darstellt. Funzt auch alles ganz wunderbar.
Wenn die Funktion zum Graph geändert wird invalidiere ich die komplette form, da sie nichts anderes beinhaltet.
Zum Problem:
Wenn ich das Fenster minimiere oder in eine andere Anwendung klicke und es dann wieder vorhole zeichnet es meine 3 Textboxn und dahinter in der gesamten Clientarea ein Großes Rotes X. Wie kann ich das verhindern bzw. wo liegt die Ursache dafür?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace DynamicGraph
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
base.OnPaint(e);
PaintEventArgs CoordinateSystemArgs = new PaintEventArgs(e.Graphics, new Rectangle(50, 50, 400, 400));
DrawCoordinateSystem(CoordinateSystemArgs, new Pen(Color.LightSteelBlue), 10);
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
DrawGraph(CoordinateSystemArgs, new Pen(Color.DarkSlateBlue));
}
private static void DrawCoordinateSystem(PaintEventArgs e, Pen pen, Int16 space)
{
pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
Point point1 = new Point();
Point point2 = new Point();
point1.X = e.ClipRectangle.Left; // Links Oben -> Max
point2.X = point1.X + e.ClipRectangle.Width; // Rechts Oben -> Max
for (int i = point1.X; i < point2.X + space; i += space)
{
point1.Y = i;
point2.Y = i;
e.Graphics.DrawLine(pen, point1, point2);
}
point1.Y = e.ClipRectangle.Top; // Links Unten -> Max
point2.Y = point1.Y + e.ClipRectangle.Height; // Rechts Unten -> Max
for (int i = point1.Y; i < point2.Y + space; i += space)
{
point1.X = i;
point2.X = i;
e.Graphics.DrawLine(pen, point1, point2);
}
pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;
//Horizontale Mittel-Linie
point1.X = e.ClipRectangle.Left;
point1.Y = e.ClipRectangle.Height / 2 + e.ClipRectangle.Top;
point2.X = point1.X + e.ClipRectangle.Width;
point2.Y = point1.Y;
e.Graphics.DrawLine(pen, point1, point2);
//Vertikale Mittel-Linie
point1.X = e.ClipRectangle.Left + e.ClipRectangle.Width / 2;
point1.Y = e.ClipRectangle.Top;
point2.X = point1.X;
point2.Y = point1.Y + e.ClipRectangle.Height;
e.Graphics.DrawLine(pen, point1, point2);
}
private void DrawGraph(PaintEventArgs e, Pen pen)
{
Point point1 = new Point();
point1.X = e.ClipRectangle.Left + e.ClipRectangle.Width / 2; //Mitte -> Horizontal
point1.Y = e.ClipRectangle.Top + e.ClipRectangle.Height / 2; //Mitte -> Vertical
for (int i = -40; i < 40; i++)
{
if (DrawGraphHelper(point1, i).Y >= e.ClipRectangle.Y
&& DrawGraphHelper(point1, i).X >= e.ClipRectangle.X
&& DrawGraphHelper(point1, i).Y <= e.ClipRectangle.Height + e.ClipRectangle.Y
&& DrawGraphHelper(point1, i).X <= e.ClipRectangle.Width + e.ClipRectangle.X
&& DrawGraphHelper(point1, i + 1).Y >= e.ClipRectangle.Y
&& DrawGraphHelper(point1, i + 1).X >= e.ClipRectangle.X
&& DrawGraphHelper(point1, i + 1).Y <= e.ClipRectangle.Height + e.ClipRectangle.Y
&& DrawGraphHelper(point1, i + 1).X <= e.ClipRectangle.Width + e.ClipRectangle.X) // Alte Lösung! e.Graphics.Clip nutzen!
{
e.Graphics.DrawLine(pen, DrawGraphHelper(point1, i), DrawGraphHelper(point1, i + 1));
}
}
}
private static Point DrawGraphHelper(Point point1, int i)
{
// x senken = nach links
// x erhöhen = nach rechts
// y senken = nach oben
// y erhöhen = nach unten
point1.X += i;
point1.Y -= (int)(Math.Pow(i, GetNumber()) / GetZoomFaktor() + GetExtension()); // Divisor bestimmt den Zoom.
return point1;
}
private static int GetNumber()
{
foreach (var item in MainForm.ActiveForm.Controls)
{
if (item is TextBox)
{
TextBox box = (TextBox)item;
if (box.Text != "")
{
if (box.Name == "PolynomTextBox")
{
int x;
if (int.TryParse(box.Text, out x))
{
return int.Parse(box.Text);
}
}
}
}
}
return 2;
}
private static int GetExtension()
{
foreach (var item in MainForm.ActiveForm.Controls)
{
if (item is TextBox)
{
TextBox box = (TextBox)item;
if (box.Text != "")
{
if (box.Name == "ExtensionsTextBox")
{
int x;
if (int.TryParse(box.Text, out x))
{
return int.Parse(box.Text);
}
}
}
}
}
return 0;
}
private static int GetZoomFaktor()
{
foreach (var item in MainForm.ActiveForm.Controls)
{
if (item is TextBox)
{
TextBox box = (TextBox)item;
if (box.Text != "")
{
if (box.Name == "ZoomTextBox")
{
int x;
if (int.TryParse(box.Text, out x))
{
return int.Parse(box.Text);
}
}
}
}
}
return 1;
}
private void Polynom_Changed(object sender, EventArgs e)
{
MainForm.ActiveForm.Invalidate();
}
private void MainForm_Activated(object sender, EventArgs e)
{
MainForm.ActiveForm.Invalidate();
}
}
}
Kann mir eigentlich nur vorstellen, daß eine deiner Funktionen in der Paint-Methode einen Fehler verursacht. Hast du schonmal probiert, die einzelnen Anweisungen in der Methode auszukommentieren, und zu schauen, wo der Fehler verursacht wird?
Weeks of programming can save you hours of planning
In der GetZoomFaktor()-Methode etc. greifst du auf die ActiveForm zu.
Hat aber dein Program keinen Focus, ist ActiveForm == Null...
Religionskriege sind Konflikte zwischen erwachsenen Menschen, bei denen es darum geht, wer den cooleren, imaginaeren Freund hat
Die ganzen Methoden GetNumber(), GetExtension() sowie GetZoomFactor() sind völliger Blödsinn (statische Methoden, welche mittels einer Schleife ein bestimmtes Control suchen ?( )
Und auch ActiveForm ist völlig überflüssig (oder gibt es bei dir mehrere MainForms???)
Alexander, wenn du ein gutes Graph-Programm sehen willst, dann schau dir mal den Link in meiner Signatur an. Dort gibt es das Programm "Graph" zum runterladen.
Leider kann ich diese Controls nicht anders Ansprechen, zumindest lässt mich mein Intellisense nicht. Die Methoden an sich sind nicht Sinnlos, nur der Weg auf dem ich auf die Controls zugreife ist sehr unbefriedigend.
das mit MainForm.Active==null war es. Danke.
Könnt ihr mir sagen welchen besseren Weg es gibt auf die 3 Textboxen zuzugreifen?
Gruß
Alex
EDIT:
while(!kopf.abstandZuWand==0)
{
kopf.abstandZuWand -= 10;
}
statische Methoden..... manchmal sieht man den Wald einfach nicht, ich hatte mich schon gewundert warum ich nicht auf die Controls zugreifen kann.
Sorry.
@ Th69
Ich glaube das deine Matheparser schon gut ist, aber es geht ja darum das ich soetwas selber hinbekomme und mich gleichzeitig mit dem Zeichnen unter Forms beschäftige. Im Moment erstmal um 2teres.
Hallo Alexander,
ich wollte dir auch nur den Code meines "Graph"-Programms als Ansichtsexemplar zur Verfügung stellen, so daß du daraus etwas lernen kannst.
Aber schön, daß du es jetzt alleine gelöst hast.