Visualizzazione dei risultati da 1 a 10 su 10
  1. #1

    [C#] Sfarfallio refresh

    Buongiorno a tutti,

    sto realizzando uno usercontrol che dovrebbe visualizzare un manico di chitarra e la pressione di alcune corde, in base ad alcuni metodi che settano una lista di corde da premere sui vari tasti del manico.

    ora, ho scritto nell'evento guitarcontrol_paint tutte le primitive grafiche per realizzare una rudimentale chitarra (con line ho disegnato le corde e i tasti), e con dei cerchietti fillellipse realizzo i tasti da premere sulle relative corde. e fin qua funziona tutto bene. ora il problema è il metodo pubblico play, che permette di cambiare tasti e corde da premere quando viene chiamato. play setta la nuova lista di tasti e corde e chiama il metodo refresh, che dovrebbe ridisegnare il controllo con la nuova configurazione. e si nota ogni qual volta viene chiamato play() uno sfarfallio molto fastidioso. vi scrivo i metodi come li ho implementati, badate che vi ho descritto una versione semplificata, in realtà i miei metodi realizzano con dei pallini grigi le corde da premere "dopo" e con dei pallini rossi le corde da premere in quel momento. play permette di scambiare i pallini grigi con quelli rossi e di impostare i nuovi pallini grigi. tramite il codice sarà tutto più chiaro.

    codice:
     public void Play(List<tasto> next)
            {
                PremiNow = PremiDopo;
                PremiDopo = next;
                this.Refresh();
            }
           
            private void GuitarControl_Load(object sender, EventArgs e)
            {
    
            }
    
            private void GuitarControl_Paint(object sender, PaintEventArgs e)
            {
                Pen p = new Pen(Color.Silver);
                SolidBrush r = new SolidBrush(Color.Red);
                SolidBrush g = new SolidBrush(Color.Gray);
                e.Graphics.FillRectangle(new SolidBrush(Color.Brown), new Rectangle(0, 0, 1020, 140));
                e.Graphics.DrawLine(p, new Point(20, 20), new Point(1000, 20));
                e.Graphics.DrawLine(p, new Point(20, 40), new Point(1000, 40));
                e.Graphics.DrawLine(p, new Point(20, 60), new Point(1000, 60));
                e.Graphics.DrawLine(p, new Point(20, 80), new Point(1000, 80));
                e.Graphics.DrawLine(p, new Point(20, 100), new Point(1000, 100));
                e.Graphics.DrawLine(p, new Point(20, 120), new Point(1000, 120));
                for (int i = 0; i < 10; i++)
                {
                    e.Graphics.DrawLine(p, new Point(i*40 -20, 10), new Point(i*40-20, 125));
                }
                foreach (tasto t in PremiDopo)
                {
                    e.Graphics.FillEllipse(g, t.tastiera * 40 - 12, t.corda * 20 - 7, 14, 14);
                }
                
                foreach( tasto t  in PremiNow){
                    e.Graphics.FillEllipse(r,t.tastiera* 40 -10, t.corda *20 - 5,10,10);
                }
       
            }

  2. #2
    Utente di HTML.it L'avatar di U235
    Registrato dal
    Mar 2006
    Messaggi
    1,539
    Ciao,
    secondo me è meglio usare direttamente il metodo OnPaint facendo un override senza aspettare l'evento paint (che si porta dietro anche l'object). Poi in questo caso credo che sia meglio usare Invalidate al posto di Refresh (che comunque chiama anche Invalidate e Update).

    comunque io farei direttamente una derivata da pictureBox al posto di un userControl.


  3. #3
    uhm ho fatto l'override su onpaint, però lo sfarfallio continua...
    inoltre ho anche provato this.invalidate() anzichè this.refresh, ma nisba, lo sfarfallio continua

    l'uso di una picturebox non me gusta, perchè mi serve creare lo usercontrol, però, magari potrei usare una picturebox all'interno dello user. ma inoltre lo sfarfallio è causato dal fatto che a ogni chiamata della primitiva drawline, ad esempio il controllo mi disegna una linea, e qui è evidente lo sfarfallio, perchè ogni volta ridisegna il componente. ma non sarebbe possibile "disegnare" il compontente senza che la reale modifica grafica venga eseguita, e solo dopo rendere effettivo il tutto? perdona la mia scarsa terminologia

  4. #4
    Utente di HTML.it L'avatar di U235
    Registrato dal
    Mar 2006
    Messaggi
    1,539
    Originariamente inviato da samuele.tosatto
    uhm ho fatto l'override su onpaint, però lo sfarfallio continua...
    inoltre ho anche provato this.invalidate() anzichè this.refresh, ma nisba, lo sfarfallio continua

    l'uso di una picturebox non me gusta, perchè mi serve creare lo usercontrol, però, magari potrei usare una picturebox all'interno dello user. ma inoltre lo sfarfallio è causato dal fatto che a ogni chiamata della primitiva drawline, ad esempio il controllo mi disegna una linea, e qui è evidente lo sfarfallio, perchè ogni volta ridisegna il componente. ma non sarebbe possibile "disegnare" il compontente senza che la reale modifica grafica venga eseguita, e solo dopo rendere effettivo il tutto? perdona la mia scarsa terminologia
    prova a postare il codice dove hai fatto l'override del paint e hai usato invalidate al posto di refresh, così magari lo provo anche io...
    ti consiglio comunque sempre una pictureBox, in modo da fare il paint solo di quello e non dell'eventuale altre cose del controllo.

    ma quanta roba disegni?

  5. #5
    codice del form:
    codice:
    using System;
    using System.Collections;
    using System.Xml;
    using System.Xml.Linq;
    using System.Data;
    using System.Text;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Drawing;
    using System.Linq;
    using System.Windows.Forms;
    using System.Linq;
    
    namespace Chitarra
    {
        public partial class Form1 : Form
        {
            int t = 0;
            List<tasto> E= new List<tasto>();
            List<tasto> D = new List<tasto>();
            List<tasto> C = new List<tasto>();
            public Form1()
            {
                InitializeComponent();
    
                E.Add(new tasto(2, 2));
                E.Add(new tasto(3, 2));
                E.Add(new tasto(4, 2));
                D.Add(new tasto(1, 2));
                D.Add(new tasto(2, 3));
                D.Add(new tasto(3, 2));
                C.Add(new tasto(2, 2));
                C.Add(new tasto(4, 3));
                C.Add(new tasto(5, 4));
                guitarControl1.Inizialize(E, D);
            }
    
            private void timer1_Tick(object sender, EventArgs e)
            {
                +t = t % 3;
                if (t == 0)
                    guitarControl1.Play(E);
                else if (t == 1) guitarControl1.Play(D);
                else guitarControl1.Play(C);
                t++;
               
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
    
            }
    
        }
    }
    codice del componente:
    codice:
    namespace Chitarra
    {
        public struct tasto {
            public int corda;
            public int tastiera;
    
            public  tasto(int corda, int tastiera)
            {
                this.corda = corda;
                this.tastiera = tastiera;
            }
        }
        public partial class GuitarControl : UserControl
        {
    
            public List<tasto> PremiNow = new List<tasto>();
            public List<tasto> PremiDopo = new List<tasto>();
            public List<tasto> buffer = new List<tasto>();
            public GuitarControl()
            {
                InitializeComponent();
            }
    
            public void Inizialize(List<tasto> now, List<tasto> dopo)
            {
                PremiNow = now;
                PremiDopo = dopo;
            }
            public void Play(List<tasto> next)
            {
                PremiNow = PremiDopo;
                PremiDopo = next;
                this.Invalidate();
            }
           
            private void GuitarControl_Load(object sender, EventArgs e)
            {
    
            }
    
            private void GuitarControl_Paint(object sender, PaintEventArgs e)
            {
                
                
               
            }
    
            private void GuitarControl_BackgroundImageChanged(object sender, EventArgs e)
            {
                
            }
            protected override void OnPaint(PaintEventArgs e)
            {
                Pen p = new Pen(Color.Silver);
                SolidBrush r = new SolidBrush(Color.Red);
                SolidBrush g = new SolidBrush(Color.Gray);
                e.Graphics.FillRectangle(new SolidBrush(Color.Brown), new Rectangle(0, 0, 1020, 140));
                e.Graphics.DrawLine(p, new Point(20, 20), new Point(1000, 20));
                e.Graphics.DrawLine(p, new Point(20, 40), new Point(1000, 40));
                e.Graphics.DrawLine(p, new Point(20, 60), new Point(1000, 60));
                e.Graphics.DrawLine(p, new Point(20, 80), new Point(1000, 80));
                e.Graphics.DrawLine(p, new Point(20, 100), new Point(1000, 100));
                e.Graphics.DrawLine(p, new Point(20, 120), new Point(1000, 120));
                for (int i = 0; i < 10; i++)
                {
                    e.Graphics.DrawLine(p, new Point(i * 40 - 20, 10), new Point(i * 40 - 20, 125));
                }
                foreach (tasto t in PremiDopo)
                {
                    e.Graphics.FillEllipse(g, t.tastiera * 40 - 12, t.corda * 20 - 7, 14, 14);
                }
    
                foreach (tasto t in PremiNow)
                {
                    e.Graphics.FillEllipse(r, t.tastiera * 40 - 10, t.corda * 20 - 5, 10, 10);
                }
                base.OnPaint(e);
            }
        }
    }

  6. #6
    Utente di HTML.it L'avatar di U235
    Registrato dal
    Mar 2006
    Messaggi
    1,539
    Ciao,
    io ho provato (nel mio pc...) questo :
    codice:
    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 WindowsFormsApplication1.Chitarra;
    
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            int t = 0;
            List<tasto> E = new List<tasto>();
            List<tasto> D = new List<tasto>();
            List<tasto> C = new List<tasto>();
            Timer timer1 = new Timer();
            public Form1()
            {
                InitializeComponent();
                this.timer1.Tick+=new EventHandler(timer1_Tick);
                this.timer1.Interval = 100;
                this.timer1.Start();
                E.Add(new tasto(2, 2));
                E.Add(new tasto(3, 2));
                E.Add(new tasto(4, 2));
                D.Add(new tasto(1, 2));
                D.Add(new tasto(2, 3));
                D.Add(new tasto(3, 2));
                C.Add(new tasto(2, 2));
                C.Add(new tasto(4, 3));
                C.Add(new tasto(5, 4));
                guitarControl1.Inizialize(E, D);
            }
            
            private void timer1_Tick(object sender, EventArgs e)
            {
                t = t % 3;
                if (t == 0)
                    guitarControl1.Play(E);
                else if (t == 1) guitarControl1.Play(D);
                else guitarControl1.Play(C);
                t++;
    
            }
    
        }
        namespace Chitarra
        {
            public struct tasto
            {
                public int corda;
                public int tastiera;
    
                public tasto(int corda, int tastiera)
                {
                    this.corda = corda;
                    this.tastiera = tastiera;
                }
            }
            public partial class GuitarControl : PictureBox
            {
    
                public List<tasto> PremiNow = new List<tasto>();
                public List<tasto> PremiDopo = new List<tasto>();
                public List<tasto> buffer = new List<tasto>();
                public GuitarControl()
                {
                    //InitializeComponent();
                }
    
                public void Inizialize(List<tasto> now, List<tasto> dopo)
                {
                    PremiNow = now;
                    PremiDopo = dopo;
                }
                public void Play(List<tasto> next)
                {
                    PremiNow = PremiDopo;
                    PremiDopo = next;
                    this.Invalidate();
                }
    
                protected override void OnPaint(PaintEventArgs e)
                {
                    Pen p = new Pen(Color.Silver);
                    SolidBrush r = new SolidBrush(Color.Red);
                    SolidBrush g = new SolidBrush(Color.Gray);
                    e.Graphics.FillRectangle(new SolidBrush(Color.Brown), new Rectangle(0, 0, 1020, 140));
                    e.Graphics.DrawLine(p, new Point(20, 20), new Point(1000, 20));
                    e.Graphics.DrawLine(p, new Point(20, 40), new Point(1000, 40));
                    e.Graphics.DrawLine(p, new Point(20, 60), new Point(1000, 60));
                    e.Graphics.DrawLine(p, new Point(20, 80), new Point(1000, 80));
                    e.Graphics.DrawLine(p, new Point(20, 100), new Point(1000, 100));
                    e.Graphics.DrawLine(p, new Point(20, 120), new Point(1000, 120));
                    for (int i = 0; i < 10; i++)
                    {
                        e.Graphics.DrawLine(p, new Point(i * 40 - 20, 10), new Point(i * 40 - 20, 125));
                    }
                    foreach (tasto t in PremiDopo)
                    {
                        e.Graphics.FillEllipse(g, t.tastiera * 40 - 12, t.corda * 20 - 7, 14, 14);
                    }
    
                    foreach (tasto t in PremiNow)
                    {
                        e.Graphics.FillEllipse(r, t.tastiera * 40 - 10, t.corda * 20 - 5, 10, 10);
                    }
                    base.OnPaint(e);
                }
            }
        }
    }
    e non ho notato nessuno sfarfallio eppure ho provato anche a lanciare il ridisegno ogni 10 millisecondi, ovviamente sfarfallavano i cerchi agli occhi umani, ma l'immagine in generale no.

  7. #7
    prova con interval=1000.... oh, se poi a te non sfarfalla c'è da sperare che nn sfarfalli nemmeno sul pc suq quale finirà sto programma che fortunatamente non è il mio.

    comunque.... non c'è un modo per "freezare" l'immagine del controllo, e riabilitarla solo quando viene ridisegnato interamete perchè secondo me lo sfarfallio è dovuto al ridisegno "in tempo reale"del componente

  8. #8
    Utente di HTML.it L'avatar di U235
    Registrato dal
    Mar 2006
    Messaggi
    1,539
    si, ho provato anche con interval 1000, come detto sono sceso fino a 10, ma niente ... ovviamente bisognerebbe vedere il tuo pc... magari si scopre che va ancora a carbone!!! (scherzo ovviamente)

    comunque fai una prova con il codice che ho postato (il tuo però ereditando dalla pictureBox).

  9. #9
    Grazie mille, non avevo visto l'accorgimento :-) ora parrebbe funzionare!!!!! XD
    a me sembra pura magia... grazie ancora...
    Adesso secondo te, anche se appesantisco un po' la grafica p.e inserendo uno sfondo di chitarra da un'immagine, resiste allo sfarfallio??

  10. #10
    Utente di HTML.it L'avatar di U235
    Registrato dal
    Mar 2006
    Messaggi
    1,539
    Originariamente inviato da samuele.tosatto
    Grazie mille, non avevo visto l'accorgimento :-) ora parrebbe funzionare!!!!! XD
    a me sembra pura magia... grazie ancora...
    Adesso secondo te, anche se appesantisco un po' la grafica p.e inserendo uno sfondo di chitarra da un'immagine, resiste allo sfarfallio??
    Figurati

    secondo me se non usi un immagine troppo "pesante" riesci ad ottenere un buon risultato.


Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.