Avatar billede egoselv Nybegynder
30. juli 2009 - 21:34 Der er 4 kommentarer og
1 løsning

C#, Hvordan opnås opdatering af GUI efter DrawLine(..) etc.

Med nedenstående kode opdateres GUI først ved overgang fra misted fokus til fokus. Hvad skal der til for øjeblikkelig opdatering?

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 PlotTest
{
    public partial class Form1 : Form
    {
        private Measure theMeasure;
        public Form1()
        {
            InitializeComponent();

            theMeasure = new Measure(this.pnlGraph);
        }

        private void btnInterval_Click(object sender, EventArgs e)
        {
            float min = Convert.ToInt32(txtMin.Text);
            float max = Convert.ToInt32(txtMax.Text);
            theMeasure.SetY(min, max);
        }

        private void btnValue_Click(object sender, EventArgs e)
        {
            float value = Convert.ToInt32(txtValue);
            theMeasure.PlotValue(value);
        }

    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace PlotTest
{
    class Measure
    {
        private float[] mValue;
        private DataPlot ValuePlot;
        private static int Index;
        private const int MAX_ARRAY = 512;

        public Measure(System.Windows.Forms.Panel p)
        {
            ValuePlot = new DataPlot(p, 0F, 10F);
            mValue = new float[MAX_ARRAY];
            Index = 0;
        }
        public void SetY(float min, float max)
        {
            ValuePlot.PlotAmplitude(min, max);
        }
        public void PlotValue(float value)
        {
            mValue[Index++] = value;
            Index %= MAX_ARRAY;
            ValuePlot.PlotData(Index, mValue, Color.Red);
        }
    }
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;

namespace PlotTest
{
    class DataPlot
    {
        Graphics plot;
        Rectangle pGrid;
        Color bgColor;
        float start, interval;
        float vmin, vmax;
        int nIntervals;

        public DataPlot(System.Windows.Forms.Panel p, float min, float max)
        {
            int x,y,w,h;

            p.BackgroundImage = new Bitmap (p.ClientSize.Width, p.ClientSize.Height, PixelFormat.Format24bppRgb);
            plot = Graphics.FromImage(p.BackgroundImage);
            bgColor = p.BackColor;
            x = Convert.ToInt32(0.1 * p.ClientSize.Width);
            y = Convert.ToInt32(0.1 * p.ClientSize.Height);
            w = Convert.ToInt32(0.85 * p.ClientSize.Width);
            h = Convert.ToInt32(0.85 * p.ClientSize.Height);
            pGrid = new Rectangle(x,y,w,h);
            PlotAmplitude(min,max);
        }
        public void PlotAmplitude(float min, float max)
        {
            plot.Clear(bgColor);
            plot.FillRectangle(Brushes.LightYellow, pGrid);
            PlotIntervals(min, max);
            DrawGrid(start, interval, nIntervals);
        }
        private void PlotIntervals(float min, float max)
        {
            if (min == max)
                min = 0.9F * max;

            start = min;
            interval = (Math.Abs(min) + Math.Abs(max)) /10.0F;
            nIntervals = 10;
        }
        private void DrawGrid(float start, float interval, int number)
        {
            int y;
            string s;
            SizeF theSize;
            Font theFont = new Font("Arial", 8);

            vmin = start;
            vmax = start + number * interval;
            plot.DrawRectangle(Pens.Black, pGrid);

            for (int i = 0; i < number; i++)
            {
                y = MakeY(pGrid, start + i * interval, vmin, vmax);
                plot.DrawLine(Pens.Black, pGrid.X, y, pGrid.X + pGrid.Width, y);
                s = String.Format("{0:f0}", start + i * interval);
                theSize = plot.MeasureString(s, theFont);
                plot.DrawString(s, theFont, Brushes.Black, pGrid.X - theSize.Width, Convert.ToInt32(y - 0.5 * theSize.Height));
            }
        }
        private int MakeY(Rectangle r, float y, float ymin, float ymax)
        {
            return (Convert.ToInt32(r.Y + r.Height - r.Height * ((y - ymin) / (ymax - ymin))));
        }
        public void PlotData(int n, float[] v, Color c)
        {
            Pen thePen = new Pen(c);
            int prev = 0;
            int x1, y1;
            int x2, y2;

            for (int i = 0; i < n; i++)
            {
                x1 = Convert.ToInt32(pGrid.X + prev * pGrid.Width / (n-1));
                x2 = Convert.ToInt32(pGrid.X + i * pGrid.Width / (n-1));
                y1 = MakeY(pGrid, v[prev], vmin, vmax);
                y2 = MakeY(pGrid, v[i], vmin, vmax);
                plot.DrawLine(thePen, x1, y1, x2, y2);
                prev = i;
            }
        }
    }
}
Avatar billede egoselv Nybegynder
30. juli 2009 - 21:49 #1
Ret følgende skrive fejl:
1. float value = Convert.ToInt32(txtValue);
  rettes til : float value = Convert.ToInt32(txtValue.Text);
2. (n-1) i nævneren erstattes med ((n-1)==0?1:(n-1))
/EGO
Avatar billede aaberg Nybegynder
31. juli 2009 - 08:44 #2
Du griber det and lidt forkert. Når man opdatere gui'en ved hjælp af et Graphics object, skal du lave alt tegnelogikken i OnPaint metoden på din Control/Form. I OnPaint metoden får du et PaintEventArgs objekt med som parameter, denne indeholder blandt andet reference til det Graphics objekt du skal bruge til at tegne med på din Control.

Her er et eksempel på en klasse som nedarver fra Panel. Klassen overrider OnPaint, og tegner et kryds hen over arealet af Kontrollen. Den har 2 ekstra Properties, som er CrossColor og CrossLineWidth. Læg mærke til at jeg kalder Invalidate() metoden inde i set-metoden på disse properties. Invalidate gør at kontrollen vil gentegne sig selv. Dvs hvis du eksempelvis ændre farven, vil kontrollen tegne sig selv forfra, og farven vil umiddelbart blive ændret.

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

namespace WindowsFormsApplication1
{
    public class CrossPanel : Panel
    {
        public CrossPanel()
        {
            this.DoubleBuffered = true;
            this.CrossColor = Color.Gray;
            this.CrossLineWidth = 2f;
        }

        private Color _crossColor;
        public Color CrossColor
        {
            get { return _crossColor; }
            set
            {
                this._crossColor = value;
                this.Invalidate();
            }
        }

        private float _crossLineWidth;
        public float CrossLineWidth
        {
            get { return _crossLineWidth; }
            set
            {
                this._crossLineWidth = value;
                this.Invalidate();
            }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

            PointF topLeft = new PointF(0f, 0f);
            PointF topRight = new PointF((float)this.Width, 0f);
            PointF bottomLeft = new PointF(0f, (float)this.Height);
            PointF bottomRight = new PointF((float)this.Width, (float)this.Height);

            Pen linePen = new Pen(this.CrossColor, this.CrossLineWidth);
            e.Graphics.DrawLine(linePen, topLeft, bottomRight);
            e.Graphics.DrawLine(linePen, bottomLeft, topRight);
           
            float delta = this.CrossLineWidth / 2f;
            RectangleF borderRect = new RectangleF(delta, delta, (float)this.Width - 2f * delta, (float)this.Height - 2f * delta);
            e.Graphics.DrawRectangle(linePen, borderRect.Left, borderRect.Top, borderRect.Width, borderRect.Height);
        }
    }
}

Prøv at copy/paste denne kode ind i en ny klasse. Du vil se at det også virker design-time i visual studio.

Jeg håber dette giver dig lidt inspiration. Ellers må du bare spørge :-)
Avatar billede egoselv Nybegynder
31. juli 2009 - 10:54 #3
Tak for responcen, jeg fordyber mig i problemet og vender tilbage ASAP.
Avatar billede egoselv Nybegynder
03. august 2009 - 12:49 #4
Tak for hjælpen "aaberg_cc", jeg har nu forstået at der er forskel på statisk og dynamisk grafik og strukturen skal opbygges derefter. Point til dig.
Avatar billede aaberg Nybegynder
03. august 2009 - 13:50 #5
Tak for det :-)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester