Entwickler-Ecke

WinForms - Größenveränderung eines abgerundeten Rechtecks


mkRE - Fr 06.11.15 23:07
Titel: Größenveränderung eines abgerundeten Rechtecks
Hallo zusammen,

ich wende mich an euch weil ich gerade verzweifelt an einer kniffligen Aufgabe arbeite.

Ich suche nach einer Lösung die folgenden Formen in einer Anwendung einzuzeichen und dann noch Größentechnisch verändern zu können mittels eines TrackBar.
Hat jemand von euch Erfahrung damit allgemein Grafics animiert größenveränderlich zu machen?

Und hat jemand schon so eine Art Form gezeichnet im Code?

Siehe Anhang:

Vielen Dank


Th69 - Sa 07.11.15 08:47

Hallo,

wie weit ist denn bisher dein Kenntnisstand bzgl. Zeichnen in Forms?
Zwei Links zum Zeichnen allgemein habe ich unter Hintergrundbild in Spiel? [http://www.entwickler-ecke.de/viewtopic.php?p=656894#656894] gepostet gehabt.

Um das (Neu-)Zeichnen per TrackBar zu ermöglichen, muß das Steuerelement einfach per

C#-Quelltext
1:
control.Invalidate();                    

neu gezeichnet werden (und im Paint-Ereignis reagierst du dann entsprechend der Eigenschaft TrackBar.Value).

PS: Eine automatische Animation würde per System.Windows.Forms.Timer-Komponente erfolgen, d.h. im Tick-Ereignis obige Methode aufrufen (dann entsprechend mit einer Animationsvariablen, z.B. currentWidth).

Edit: Die konkrete Form, also ein abgerundetes Rechteck, zeichnet man am besten per GraphicsPath.
Hier ein Artikel mit Code: Extended Graphics - An implementation of Rounded Rectangle in C# [http://www.codeproject.com/Articles/5649/Extended-Graphics-An-implementation-of-Rounded-Rec] (such nach der Methode DrawRoundRectangle mit der aufgerufenen Methode GetRoundedRect).


jfheins - Sa 07.11.15 12:49

Ich habe hier schonmal einen Stern veränderlich gezeichnet: http://www.delphipraxis.net/142318-stardesigner-make-your-star.html#post965130

Bei dem Stern hatte ich eine Umrechnung von Polar in Bildkoordinaten. Polarkoordinaten brauchst du eher nicht, aber eine solche Umrechnungsfunktion ist schon praktisch.
Die legt nämlich auch gleich den Koordinatenursprung in die Bildmitte und spiegelt die Y-Achse. Da wo ich InnerRadius.Value geschieben habe, kannst du natürlich auch Konstanten einsetzen, oder ein vielfaches der PictureBox Höhe oder Breite - dann würde die Form mit skalieren.


mkRE - Sa 07.11.15 22:24

Hallo jfheins

danke für die Stern Beispiele die Beispiele schaue ich mir natürlich an und gucke was ich evtl davon verwenden kann.

Ich werde erstmal den weg von Th69 verwenden vielleicht hat sich dann auch das Thema erledigt.

Trotzdem danke!!


mkRE - Sa 07.11.15 22:41

Hallo Th69,

mein Kenntnisstand mit Zeichnen in Forms ist = 0 :-).

Jedoch bin ich gestern abend schon so weit gekommen, ein Viereck mit dem Trackbar auch ein Rechteck zu stauchen.
Habe dazu Refresh() verwendet. Aber ich denke mit Invalidate() wird es auch funktionieren.
Danke für den Tipp.

Was meintest du mit der Animationsvariable currentWidth?

Ich mache das alle momentan folgendermaßen:

C#-Quelltext
1:
2:
3:
Graphics x = this.CreateGraphics();
x.FillRectangle(Brushes.Red, xPos, yPos, xWidth, yHight);
// ...

Wie finde ich den hier aus dem Rechteck die aktuelle Höhe und Breite?
Kannst du mir da ggf. eine Gedankenstütze geben?

Anderseits gehe ich daran die Methode DrawRoundRectangle zu verwenden da danke ich dir sehr für den Tipp
sieht so aus als wärs das was ich gesucht habe.

Viele Grüße

Moderiert von user profile iconTh69: C#-Tags hinzugefügt


mkRE - So 08.11.15 00:40

Hallo Th69,

ich habe mich jetzt an deinen Link versucht.
Wie beschrieben habe ich eine eigene Klasse in der Form erstellt.

Jedoch bekomme ich folgende Fehlermeldung, wenn ich ExtendedGraphics x = this.CreateGraphics(); anwende.
Zitat:
Fehler 2 Eine implizite Konvertierung vom Typ "System.Drawing.Graphics" in "System.Drawing.Extended.ExtendedGraphics" ist nicht möglich. C:\Users\User\documents\ ..............

Kannst du mir da weiterhelfen?

Moderiert von user profile iconTh69: C#-Tags hinzugefügt
Moderiert von user profile iconTh69: Quote-Tags hinzugefügt


Th69 - So 08.11.15 08:31

Hallo,

statt CreateGraphics solltest du im Paint-Ereignis auf e.Graphics zugreifen.

Und die Klasse hat nichts (direkt) mit der Graphics-Klasse zu tun, sondern du mußt diese nur im Paint-Ereignis benutzen, d.h.

C#-Quelltext
1:
2:
ExtendedGraphics extendedGraphics = new ExtendedGraphics(e.Graphics);
extendedGraphics.DrawRoundRectangle(...);


Ralf Jansen - So 08.11.15 12:27

Zitat:
Habe dazu Refresh() verwendet. Aber ich denke mit Invalidate() wird es auch funktionieren.

Invalidate ist normalerweise zu bevorzugen. Refresh zeichnet im Gegensatz zu Invalidate sofort (Refresh ist die Kombination aus Invalidate und Update)
Bedeutet wenn du mehrere Controls auf der Form hast und änderst zum Beispiel durch eine Aktion mehrere gleichzeitig (z.B es reagieren alle auf ein resize der Form) werden alle geändert und alle zeichnen neu.

Bei Refresh : 1.Control resizen -> neuzeichnen -> 2.Control resizen -> neuzeichnen -> 3.Control resizen -> neuzeichnen etc.
Bei Invalidate : 1.Control resizen -> 2.Control resizen -> 3.Control resizen etc. -> neuzeichnen

Invalidate ist potentiell weniger aufwendig und weniger Flicker anfällig.


mkRE - Mo 09.11.15 20:58

Hallo Th69,

ich danke dir für den Tipp bzw. den Denkanstoß :-).
Ich melde mich sobald ich das geprüft habe.

user profile iconTh69 hat folgendes geschrieben Zum zitierten Posting springen:
Hallo,

statt CreateGraphics solltest du im Paint-Ereignis auf e.Graphics zugreifen.

Und die Klasse hat nichts (direkt) mit der Graphics-Klasse zu tun, sondern du mußt diese nur im Paint-Ereignis benutzen, d.h.

C#-Quelltext
1:
2:
ExtendedGraphics extendedGraphics = new ExtendedGraphics(e.Graphics);
extendedGraphics.DrawRoundRectangle(...);



Allgemein wollte ich mal fragen wo wäre es einfacher zu Zeichen in WPF oder WinForms?

Viele Grüße


mkRE - Mo 09.11.15 21:13

Hallo Ralf,

Ich habe leider das problem gehabt, wenn ich Invalidate in einem Ereignis angewendet habe und dahinter sofort neu geu´zeichnet habe, war das formular leer.

Bsp: Buttun Click: da habe ich zuerst Invalidate() durchgeführt und dahinter neu gezeichnet. Ohne Ergebnis.
Habe ich es durch Refresh() ersetzt, mit Erfolg gezeichnet. Erklärt aber das es eine Kombination ist wie du schon beschrieben hast.
Ich werde das erneut mit Invalidate() ausprobieren, weil ich gemerkt habe das auf einem Anderen Rechner diese Anwendung genau wie du beschrieben hast Flickert.



user profile iconRalf Jansen hat folgendes geschrieben Zum zitierten Posting springen:
Zitat:
Habe dazu Refresh() verwendet. Aber ich denke mit Invalidate() wird es auch funktionieren.

Invalidate ist normalerweise zu bevorzugen. Refresh zeichnet im Gegensatz zu Invalidate sofort (Refresh ist die Kombination aus Invalidate und Update)
Bedeutet wenn du mehrere Controls auf der Form hast und änderst zum Beispiel durch eine Aktion mehrere gleichzeitig (z.B es reagieren alle auf ein resize der Form) werden alle geändert und alle zeichnen neu.

Bei Refresh : 1.Control resizen -> neuzeichnen -> 2.Control resizen -> neuzeichnen -> 3.Control resizen -> neuzeichnen etc.
Bei Invalidate : 1.Control resizen -> 2.Control resizen -> 3.Control resizen etc. -> neuzeichnen

Invalidate ist potentiell weniger aufwendig und weniger Flicker anfällig.


Was ich vorhabe, ist ein Gegenstück mit einer gewissen Kraft zu stauchen. Arbeite gerade erstmal an den Grundformeln.
Dort wird es einige Parameter geben wie Geschwindigkeit, Kraft, Wärme usw. Aber zuerst muss ich mal hinbekommen das vernümftig zu Zeichen :-)
Die Simulation für ein Werkstück ohne die oben genannten Parameter funktioniert jedoch fehlt mir noch der Tipp von Th69 für den Radius und dann gehts ins eingemachte :-).

Viele Grüße


Ralf Jansen - Mo 09.11.15 21:43

Zitat:
Bsp: Buttun Click: da habe ich zuerst Invalidate() durchgeführt und dahinter neu gezeichnet. Ohne Ergebnis.

Du hast im Click Ereignis gezeichnet? Dann ist das das Problem. Jedes zeichnen musst du im Paint Ereignis ausführen.

Das was du im Click zeichnest ist nicht permanent. Jedes mal wenn neu gezeichnet werden muß wird der Paint Event ausgeführt. Zum Beispiel wenn du die Form minimierst/maximierst/resized und deshalb neugezeichnet werden müßte wird der Paint ausgeführt und natürlich nicht Click oder sonstwas. Es würde also nix gezeichnet werden und deine Controlfläche wäre leer. Oder anders ausgedrückt das was du irgendwo zeichnest wird sich nirgendwo gemerkt es reicht also nicht das einmal von irgendwo zu machen das zeichnen muß jedesmal erfolgen wenn ein neuzeichnen nötig ist und dazu gibt es den PaintEvent.

Du würdest also in Click irgendwas ändern zum Beispiel die Daten ändern die Einfluß auf das zeichnen haben udn Invalidate aufrufen. Invalidate wird dafür sorgen das kurzfristig mal Paint aufgerufen wird und dort muß dann das zeichnen erfolgen.

Zitat:
Allgemein wollte ich mal fragen wo wäre es einfacher zu Zeichen in WPF oder WinForms?


WPF ist die aktuellere Technik und damit auf vieles besser vorbereitet. Wenn du also weder in WPF noch in Winforms Vorkenntnisse hast und sowieso eins davon erlernen musst nimm WPF. Ich würde aber nicht sagen das du das tun solltest weil es einfacher. Viele würden vermutlich sogar sagen das Winforms einfacher ist. Das hängt aber eher damit zusammen das, mit dem Modell wie Winforms funktioniert, viele schon Vorkenntnisse mitbringen und sich dort leichter tun, mich eingeschlossen. Wenn du aber nicht durch Vorkenntnisse belastet bist halt dich an WPF.


mkRE - So 15.11.15 22:23

Hallo zusammen ich konnte eure letzten Tipps noch nicht ausprobieren.
Melde mich nur das dieses Thema weiterhin für mich interessant ist und noch nicht alles klar ist.

Bitte habt Geduld.

Bis demnächst, melde mich mit Ergebnissen :-)

Viele Grüße


1mkRE - Sa 28.11.15 21:47

Hallo zusammen,

ich habe es jetzt hinbekommen ein abgerundetes Rechteck zu verformen.
Alles funktionierte super. Leider war es nicht meinen Anforderungen entsprechend.

So habe ich mich entschieden dieses Rechteck mit zwei Halbkreisen zu verbinden mittels Pie siehe Bild.

Die Animation sieht ganz gut aus jedoch stört mich hier an einigen stellen das Flackern der gezeichneten Bilder im Panel.

ich bekomme es einfach nicht hin auch mit den Gegenmaßnahmen z.B. hier [Artikel] Flackernde Controls und flackerndes Zeichnen vermeiden [http://www.mycsharp.de/wbb2/thread.php?threadid=59978]
helfen mir nicht weiter. Ich weiß halt nicht wo ich die DoubleBuffered Eigenschaft usw. einfügen soll.
Habe es im Panel Paint erreignis ausprobiert, leider sehe ich da keinen großen erfolg.

Folgendes wird gezeichnet:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
private void pPanel_Paint(object sender, PaintEventArgs e)
{
    this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
    this.DoubleBuffered = true;

    e.Graphics.FillRectangle(Brushes.Black, xPosOben, yPosOben, 65020);
    e.Graphics.FillRectangle(Brushes.Black, xPosUnten, yPosUnten, 65020);
    e.Graphics.FillPie(Brushes.Green, LeftanglePosX, LeftanglePosY, LeftangleWidth, LeftangleHight, 90.0f180.0f);
    e.Graphics.FillPie(Brushes.Green, anglePosX, anglePosY, angleWidth, angleHight, -90.0f180.0f);
    e.Graphics.FillRectangle(Brushes.Green, xPos, yPos, xWidth, yHight);
}

Könnt ihr mir da weiterhelfen?

Vielen Dank.

Gruß

Moderiert von user profile iconTh69: C#-Tags hinzugefügt
Moderiert von user profile iconTh69: URL-Tag hinzugefügt


1mkRE - Sa 28.11.15 21:48

Siehe Bild:


Mathematiker - Sa 28.11.15 21:57

Hallo,
user profile icon1mkRE hat folgendes geschrieben Zum zitierten Posting springen:
Die Animation sieht ganz gut aus jedoch stört mich hier an einigen stellen das Flackern der gezeichneten Bilder im Panel.

Obwohl ich von C# keine Ahnung habe, vermute ich, dass folgender Weg auch bei C# möglich ist:
1. Bitmap im Speicher erzeugen
2. Grafik im Bitmap zeichnen
3. Bitmap auf dein Element (Panel?) kopieren
4. Bitmap löschen
Beim Schnellgoogeln fand ich:
https://msdn.microsoft.com/de-de/library/aa287582(v=vs.71).aspx

Vielleicht hilft es ja etwas.
Beste Grüße
Mathematiker


1mkRE - Sa 28.11.15 22:09

Hi Mathematiker,

sieht verlockend aus dein Link.
So kompensiere ich mit Sicherheit das flackern.

Ich warte noch mögliche Antworten von Ralf Jansen oder Th69 ab vielleicht
haben die noch einige Tipps wie ich das Flackern im bei direkten Zeichnen aufs Panel verhindere bzw. vermeide.

Die Verformung des Rechtecks in dieses gerundete gepresste "Rechteck" arbeitet in einem Interval von 10ms.
Das flackern nervt total :-(.


Ralf Jansen - Sa 28.11.15 22:17

Du solltest vom Panel ein eigenes Panel ableiten und in dessen Konstruktor dann die OptimzeDoubleBuffer Option setzen.
Beispiel hier [http://www.entwickler-ecke.de/viewtopic.php?t=114803].


Th69 - So 29.11.15 11:43

Durch

C#-Quelltext
1:
this.DoubleBuffered = true;                    

wird nur die Form als DoubleBuffered markiert, nicht das enthaltene Panel.


mkRE - So 29.11.15 23:33

Hallo Ralf danke für den Tipp ich kämpfe gerade damit wie ich das realisiere.
Das ableiten ist kein Problem aber wie realisiere ich das hab nie mit Steuerelementen vererbt brauchte ich bis dato nicht :-(.


mkRE - Di 01.12.15 22:38

Hallo zusammen,

ich brauche ggf. etwas denk Unterstützung.

ich habe jetzt eine Klasse wie folgt erstellt:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
    public partial class UserControl1 : Panel
    {
        public UserControl1(): base()
        {
            this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer, true);

        }
    }

und zeichne jetzt wie folgt:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
        private void UserControl1_paint(object sender, PaintEventArgs e)
        {
            e.Graphics.FillRectangle(Brushes.Black, xPosOben, yPosOben, 65020);

            e.Graphics.FillRectangle(Brushes.Black, xPosUnten, yPosUnten, 65020);
            e.Graphics.FillPie(Brushes.Green, LeftanglePosX, LeftanglePosY, LeftangleWidth, LeftangleHight, 90.0f180.0f);
            e.Graphics.FillPie(Brushes.Green, anglePosX, anglePosY, angleWidth, angleHight, -90.0f180.0f);


            e.Graphics.FillRectangle(Brushes.Green, xPos, yPos, xWidth, yHight);


            lblStrokeValue.Text = angleHight.ToString();
        }

also wie vorher jedoch mit einem vererbten Steuerelement.

Trotzdem flackern zwei der elemente und zwar sind es auffälligerweise die letzten beiden objekte:

C#-Quelltext
1:
2:
e.Graphics.FillPie(Brushes.Green, anglePosX, anglePosY, angleWidth, angleHight, -90.0f180.0f);
e.Graphics.FillRectangle(Brushes.Green, xPos, yPos, xWidth, yHight);

das Label mal außen vor gelassen. Das zeigt mir nur die Stauchhöhe als Zahl.

Habt Ihr eine Idee?

Viele Dank für die Tipps Ralf und TH69.

Moderiert von user profile iconTh69: C#-Tags hinzugefügt


mkRE - Do 03.12.15 22:10

Hallo zusammen,

hat jemand ggf. eine Idee wo ich einen Fehler mache?
Leider Falckern die gezeichneten Element so wie oben beschrieben auch mir Vererbung.

Viele Grüße


Th69 - Fr 04.12.15 08:55

Setze dann mal in deinem UserControl

C#-Quelltext
1:
this.DoubleBuffered = true;                    

(steht ja auch so in dem verlinkten Artikel)


Ralf Jansen - Fr 04.12.15 10:57

Die DoubleBuffered Property macht das gleiche wie SetStyle. Bei DoubleBuffered fehlt nur das setzen von UserPaint. DoubleBuffered würde als nur die Flags setzen die man eh bereits gesetzt hat.

Wenn es flackert muß ja irgendetwas ein Neuzeichnen ausgelöst haben und wenn du irgendwie eine Bewegung darstellen willst drehst du vermutlich an den benutzen Variablen im Paint Event. Den Code solltest du vielleicht mal zeigen. Nebenbei solltest du vielleicht noch ResizeRedraw bei SetStyle aufnehmen damit beim resizen neugezeichnet wird (sollte aber nix mit dem flackern zu tun haben).


mkRE - Fr 04.12.15 13:47

Hallo Ralf,

ja genau es wird eine Bewegung durchgeführt. Die dazugehörigen Werte werden vom tTimer neu beschrieben und dahinter löse ich das Invalidate aus.
Vielleicht ist in meiner Unordnung durch das viele testen ein unüberlegter Wurm, jedoch erkenne ich grad nicht wo er sitzt.
Bitte beachte es handelt sich um ein Test Projekt :-).


Hier einmal der Code:


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing.Extended;


namespace Pressen
{

    public partial class fForm : Form
    {

        public float xWidth;
        public float yHight;
        public float xPos;
        public float yPos;
        public float rRadius;
        public float angleWidth;
        public float angleHight;
        public float LeftangleWidth;
        public float LeftangleHight;
        public int xPosOben;
        public int yPosOben;
        public int xPosUnten;
        public int yPosUnten;
        public float anglePosX;
        public float anglePosY;
        public float LeftanglePosX;
        public float LeftanglePosY;
        public float Target;



        public fForm()
        {
            InitializeComponent();
        }

        private void fForm_Load(object sender, EventArgs e)
        {
            xWidth = 200.0f;
            yHight = 150.0f;
            angleWidth = 1.0f;
            angleHight = 151.0f;
            LeftangleWidth = 1.0f;
            LeftangleHight = 151.0f;
            xPos = 245.0f;
            yPos = 100.0f;
            xPosOben = 30;
            yPosOben = 80;
            xPosUnten = 30;
            yPosUnten = 250;
            anglePosX = 445.0f;
            anglePosY = 99.0f;
            LeftanglePosX = 245.0f;
            LeftanglePosY = 99.0f;
            Target = (float)Convert.ToDouble(txtTarget.Text);
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            tTimer.Enabled = true;
            txtTarget.ReadOnly = true;
        }

        private void tTimer_Tick(object sender, EventArgs e)
        {

            if (Target <= yHight)
            {

                // Verformtes Rechteck
                xPos -= 1.4f;
                yPos += 1.0f;
                xWidth += 3.0f;
                yHight -= 1.0f;
                
                // Verformtes Pie rechts
                angleWidth += 2.0f;
                angleHight -= 1.0f;
                anglePosY += 1.0f;
                anglePosX += 0.5f;

                // Verformtes Pie links
                LeftangleWidth += 2.0f;
                LeftangleHight -= 1.0f;
                LeftanglePosY += 1.0f;
                LeftanglePosX -= 2.3f;

                // Position Pressendes Rechteck
                yPosOben += 1;

                UserControl1.Invalidate();
            }
            else
            {
                tTimer.Enabled = false;
                txtTarget.ReadOnly = false;
                xWidth = 200.0f;
                yHight = 150.0f;
                angleWidth = 1.0f;
                angleHight = 151.0f;
                LeftangleWidth = 1.0f;
                LeftangleHight = 151.0f;
                xPos = 245.0f;
                yPos = 100.0f;
                xPosOben = 30;
                yPosOben = 80;
                xPosUnten = 30;
                yPosUnten = 250;
                anglePosX = 445.0f;
                anglePosY = 99.0f;
                LeftanglePosX = 245.0f;
                LeftanglePosY = 99.0f;
            }
            
        }

        private void btnStop_Click(object sender, EventArgs e)
        {
            tTimer.Enabled = false;
        }        

        private void txtTarget_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == Convert.ToChar(Keys.Return))
            {

                if (txtTarget.Text != "")
                {
                    try
                    {
                        Target = (float)Convert.ToDouble(txtTarget.Text);

                        if ((Target >= yHight) || (Target < 55.0))
                        {
                            Target = 60.0f;
                            txtTarget.Text = Convert.ToString(60);
                            MessageBox.Show("Target value not valid!!!");
                        }
                        else
                        {
                            MessageBox.Show("New Target set.");
                        }
                    }
                    catch
                    {
                        MessageBox.Show("Not a valid value");
                        Target = 60.0f;
                        txtTarget.Text = Convert.ToString(60);
                    }
                }
                else
                {
                    MessageBox.Show("Please input a number!");
                    Target = 60.0f;
                    txtTarget.Text = Convert.ToString(60);
                }
            }
        }

        private void UserControl1_paint(object sender, PaintEventArgs e)
        {           
            lblStrokeValue.Text = angleHight.ToString();
            e.Graphics.FillRectangle(Brushes.Black, xPosOben, yPosOben, 65020);
            e.Graphics.FillRectangle(Brushes.Black, xPosUnten, yPosUnten, 65020);
            e.Graphics.FillPie(Brushes.Green, anglePosX, anglePosY, angleWidth, angleHight, -90.0f180.0f);
            e.Graphics.FillPie(Brushes.Green, LeftanglePosX, LeftanglePosY, LeftangleWidth, LeftangleHight, 90.0f180.0f);
            e.Graphics.FillRectangle(Brushes.Green, xPos, yPos, xWidth, yHight);
        }
    }
}



C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Pressen
{
    public partial class UserControl1 : Panel
    {

        public UserControl1(): base()
        {
            //this.DoubleBuffered = true;
            this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer, true);
        }
    }
}


Algemein danke für eure Hilfe.

TH69 ich habe trotzdem mal versucht nur das

C#-Quelltext
1:
this.DoubleBuffered = true;                    

zu verwenden ohne den SetStyle Flags

C#-Quelltext
1:
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer, true);                    

aber keine Änderung.

Habe SetStyle verwendet weil es bei den Links und Unterlinks empfohlen wurde zu verwenden.

Viele Grüße


Ralf Jansen - Fr 04.12.15 14:10

Würde da kein Flackern erwarten.

Du meinst aber echtes Flackern?
Und nicht nur ein wenig Kantenflimmern oder zuckeligen Ablauf der Animation?
Dann muß ich sagen es ist halt nur Winforms und ein normaler Timer hat num mal kein garantiertes Syncing. Das neuzeichnen erfolgt so nicht in annähernd in gleichen Abständen.
Wenn du das brauchst müßtest du dich mit Multimedia Timern auseinander setzen. Die währen entsprechend akkurat.


Th69 - Fr 04.12.15 15:13

Welchen Wert hast du denn für den Timer.Tick eingestellt?
Da der WinForms-Timer nur eine Auflösung von ca. 15ms hat, sind kleinere Werte unsinnig.

PS: Und im Paint solltest du nur zeichnen, keine Controls ansprechen (d.h. z.B. lblStrokeValue.Text = angleHight.ToString() besser im Timer o.ä. setzen).


mkRE - Fr 04.12.15 15:49

Hallo Ralf,

achso ja genau die Frage ist ob wir vom selben Flackern reden.
Die bzw. zwei der gezeichneten Objekte im Bild blitzen kurz weiß auf aber wenn ich es richtig betrachte passt die Größe jedoch ist in dem Moment die vorgegebene Farbe weg
und für ein Augenzwinkern weiß. Das ist der Effekt der dort ensteht. Das kommt aber bei einer Bewegung von 90 nur maximal 5 mal vor.
Wie ist den das Flimmern von euch gedacht?

Multimedia Timer schaue ich mir an und vielleicht hilft das ja "Vom Naming" hört es sich passend an.
Wie realisiert man den eigentlich "Reale Bewegungen" z.B. von Maschinen dort würden so eine Art Flackern auch nicht gerade schön aussehen?
Dort werden die Intervalle ggf. nicht vom Timer aber von einer externen Signal Flanke ausgelöst.

Viele Grüße


mkRE - Fr 04.12.15 15:53

Hallo Th69,

ja das ansprechen des Controls im Paint habe ich entfernt danke für den Tipp.
Der Timer ist auf Intervall von 200 eingestellt hatte ihn auch schon auf 100 und auch kleiner gehabt bei meinen ersten versuchen.
Ich hab leider keine Unterschiede erkannt. Das passiert einfach sporadisch mindestens ein mal blinken die Objekte auf :-(.

Viele Grüße


Ralf Jansen - Fr 04.12.15 15:54

Weiß blitzen hört sich nach ~richtigem~ Flackern an ;)
Das kann auch Graphiktreiber/Karten abhängig sein. Vielleicht hilft es dir wenn du in Paint auch den Control Hintergrund einmal komplett zeichnest.

Also z.B ein

C#-Quelltext
1:
e.Graphics.FillRectangle(Brushes.Gray, e.ClipRectangle.X, e.ClipRectangle.X, e.ClipRectangle.Width, e.ClipRectangle.Width);                    

mit einem passenden Brush.


mkRE - Fr 04.12.15 20:04

Hallo Ralf ich hab es vorhin auch mit dem Hintergrund versucht leider ohne Änderung.
Lese mich gerade in den Multimedia Timer ein und versuche mal ob es besser wird.

Viele Grüße


mkRE - Sa 05.12.15 11:19

Hallo Ralf,

der Multimedia Timer funktioniert ohne Flackern und sonstiges habe es gestern noch probiert aber nicht mehr geschafft zu schreiben.
Kein Flackern!!:-) Super!!! Der Stauchprozess läuft Flackerfrei.

Aber ich kann im Timer Tick keine Steuerelemente ansprechen da bricht das Program ab mit folgender Meldung:
Zitat:
System.InvalidOperationException

{"Ungültiger threadübergreifender Vorgang: Der Zugriff auf das Steuerelement txtTarget erfolgte von einem anderen Thread als dem Thread, für den es erstellt wurde."}

Da schaue ich noch nach was es sein kann. Habt ihr eine Idee?

Moderiert von user profile iconTh69: Quote-Tags hinzugefügt


Th69 - Sa 05.12.15 12:01

Da verweise ich (auch wieder mal) auf [FAQ] Controls von Thread aktualisieren lassen (Control.Invoke/Dispatcher.Invoke) [http://www.mycsharp.de/wbb2/thread.php?threadid=33113]


mkRE - Sa 05.12.15 18:51

Hallo Th69,
danke für den Tipp meine Frage nicht bösen nehmen :-).
Jetzt muss ich es hinkriegen meine Steuerelemente anzusprechen.

Viele Grüße


mkRE - Di 08.12.15 00:42

Hallo zusammen :-).
Also jetzt geht auch die Anzeige des Labels wiedermal viel von euch dazu gelernt und das Threading aufgefrischt :-).
Danke euch beiden Ralf Jansen und Th69!!

Das flackern kommt trotzdem ab und an noch vor es wird wohl tatsächlich an der Grafikkarte oder sonstigem liegen.
Morgen versuche ich mal die Applikation auf einem anderen PC laufen zu lassen und beobachten ob es an verschiedenen PC auch flackert.
Bei 5 versuchen Flackerte es nur einmal auf, jedoch wenn ich den Timer Interval erhöhe z.B. 200 anstatt 100 dann wird das Flackern mehr.

Ich habe bei dem Multimedia Timer noch nicht verstanden wie die Auflösung bzw. Resolution funktionieren soll. Hab ihr eine Ahnung?

Viele Grüße