animierten Rahmen um Controls zeichnen

zirag

Erfahrenes Mitglied
Hallo Leutz,

ich bin noch recht neu in der .NET Programmierung und programmiere mit C#.
Ich schildere mal kurz, was ich vorhabe:
Ich möchte gerne, dass beim Fokuswechsel ein Rahmen um das Control gezeichnet wird, was den Fokus besitzt. Soweit läuft das auch schon. Nun möchte ich allerdings, dass der Rahmen (nennen wir es mal) animiert wird. D.h. er ist etwas größer und skaliert sich dann auf die Endgröße immer kleiner.

Ich habe schon versucht mit einer Schleife die Größe immer kleiner werden zu lassen und das Rechteck neu zeichnen zu lassen, das ging auch etwas, nur seeeehr unperformant. Die Buttons blieben erstmal transparent, wegen der Schleife und dem 50ms Delay zwischen jeder Größenänderung.

Ich hoffe mir kann einer da auf die Sprünge helfen :)

Hier der Code, wie ich den Rahmen momentan zeichne:
(EDIT) Hier der aktuelle Code, sobald ich in der while Schleife im gotFocus Eventhandler das Delay aktiviere (und da hätte ich nun meine Animation erwartet) erscheint der rahmen erst später. Aber eigentlich sollte er doch in jedem Schleifendurchgang das OnPaint aufrufen oder nicht?
Code:
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;
using System.Threading;

namespace FocusTest
{
    public partial class Form1 : Form
    {
        Pen p = new Pen(Color.Violet, 2);
        Rectangle rect;
        

        public Form1()
        {
            InitializeComponent();
            
            p.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
           
            this.Activated += new EventHandler(Form1_Activated);
        }

        void Form1_Activated(object sender, EventArgs e)
        {
            foreach (Control ctrl in this.Controls)
            {
                ctrl.GotFocus += new EventHandler(ctrl_GotFocus);
                
                
            }
        }

        void ctrl_GotFocus(object sender, EventArgs e)
        {
            Control ctrl = (Control)sender;
            textBox1.Text = ctrl.Name.ToString();
            rect = ctrl.Bounds;
            rect.Inflate(2, 2);
            int endSize = rect.Height;
            rect.Inflate(20, 20);
            while (rect.Height > endSize)
            {
                rect.Inflate(-1,-1);
                
                //Thread.Sleep(50);
                Invalidate();
            }
        }
        

        

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            e.Graphics.DrawRectangle(p, rect);
            
        }
    }
}
 
Zuletzt bearbeitet:
Sorry für den Doppelpost, aber ich habe es nun hinbekommen mit einem Timer.
Falls jemand sowas auch mal vorhat, poste ich nun hier den funktionierenden Code.
Vielleicht kann mir ja trotzdem jemand sagen warum das erste nicht funktioniert und ob es da noch eine elegantere Lösung gibt. Würde mich mal interessieren.

Hier nun die funktionierende Version:
Code:
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;
using System.Threading;

namespace FocusTest
{
    public partial class Form1 : Form
    {
        Pen p = new Pen(Color.Violet, 2);
        Rectangle bigRect;
        Rectangle smallRect;
        System.Windows.Forms.Timer t = new System.Windows.Forms.Timer();

        public Form1()
        {
            InitializeComponent();
            this.DoubleBuffered = true;
            p.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
            t.Interval = 20;
            t.Tick += new EventHandler(t_Tick);
            this.Activated += new EventHandler(Form1_Activated);
        }

        void Form1_Activated(object sender, EventArgs e)
        {
            foreach (Control ctrl in this.Controls)
            {
                ctrl.GotFocus += new EventHandler(ctrl_GotFocus);
                
                
            }
        }

        void ctrl_GotFocus(object sender, EventArgs e)
        {
           
            Control ctrl = (Control)sender;
            textBox1.Text = ctrl.Name.ToString();
            smallRect = ctrl.Bounds;
            smallRect.Inflate(2, 2);
            bigRect = smallRect;
            bigRect.Inflate(20, 20);
            t.Start();
            
        }

        void t_Tick(object sender, EventArgs e)
        {
            if (bigRect.Width > smallRect.Width)
            {
                bigRect.Inflate(-1, -1);
                Invalidate();
            }
            else
            {
                t.Stop();
            }
        }
        

        

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            e.Graphics.DrawRectangle(p, bigRect);
        }
    }
}
 

Neue Beiträge

Zurück