• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Dziwne zachowanie funkcji wywoływanej w konstruktorze

0 głosów
487 wizyt
pytanie zadane 20 lipca 2018 w C# przez profesorek96 Szeryf (91,420 p.)
Drodzy koledzy.

Ostatnio postanowiłem strzelić sobie apkę rysującą gwiazdę jako kształt z tablicy punktów w WinFormsie.

Napisałem do tego funkcję która będzie rysować figurę w komponencie panel.

Chciałbym ją wywołać na starcie po zainicjalizowaniu komponentów w konstruktorze, jako ostatnia linijka. Efekt jaki chciałem uzyskać to taki by po włączeniu apki figura została narysowana. Niestety po mimo że funkcja tam jest wywoływana to figura się nie rysuje. Myślałem o zastosowaniu timera, by timer po 100ms wywołał tą funkcję rysująca ale nie uważam tego za ładne rozwiązanie.

Czy jest na to jakaś inna rada ?

2 odpowiedzi

0 głosów
odpowiedź 20 lipca 2018 przez Qwerty96 Stary wyjadacz (13,580 p.)
wybrane 22 lipca 2018 przez profesorek96
 
Najlepsza
Zapewne wszystko co rysujesz w konstruktorze jest wymazywane przy pierwszym odrysowaniu okna przed jego wyświetleniem. Procedurę rysującą możesz podpiąć pod zdarzenie Paint lub nadpisać metodę OnPaint.
komentarz 20 lipca 2018 przez profesorek96 Szeryf (91,420 p.)
Niestety podpięcie pod zdarzenie paint nie powoduje poprawy, wręcz przeciwnie powoduje ciągłe migotanie.
komentarz 21 lipca 2018 przez Qwerty96 Stary wyjadacz (13,580 p.)

Dobra, zajrzałem na Twojego githuba i popatrzyłem, co ja bym poprawił. Po pierwsze jedyne miejsce, w którym należy wywołać funkcję draw_star powinno być przy odrysowaniu w metodzie podpiętej pod zdarzenie Paint panelu. Po drugie funkcja draw_star niech przyjmuje argument typu Graphics i niech z niego korzysta przy rysowaniu. W handlerze Paint przekaż do draw_star wartość e.Graphics, gdzie e jest drugim parametrem handlera. Po trzecie wszystkie wywołania draw_star w swoim kodzie zamień na panel1.Invalidate(). I po czwarte, żeby wyeliminować efekt migotania np. przy przesuwaniu suwaka od deformacji ustaw właściwość DoubleBuffered panelu na true (właściwość ta jest chroniona, więc musisz ją ustawić przez refleksję lub stworzyć własny panel dziedziczący z klasy Panel).

Tu masz plik form1.cs, który zmodyfikowałem według tego co napisałem. Żadnego innego pliku nie modyfikowałem.

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.Reflection;

namespace Star_generator
{
    public partial class Form1 : Form
    {
        ColorDialog line;
        ColorDialog fill_shape;
        
        public Form1()
        {
            InitializeComponent();
            
            Bt_Color_line.BackColor=Color.Black;
            Bt_Color_fill.BackColor=Color.Silver;
            Bt_Color_fill.Enabled = false;
            line = new ColorDialog();
            fill_shape = new ColorDialog();
            line.Color = Color.Black;
            fill_shape.Color = Color.Silver;
            timer1.Start();

            typeof(Panel).InvokeMember("DoubleBuffered", BindingFlags.SetProperty
            | BindingFlags.Instance | BindingFlags.NonPublic, null,
            panel1, new object[] { true });

            panel1.Paint += (sender, e) => draw_star(e.Graphics);
        }

        private void Bt_Color_line_Click(object sender, EventArgs e)
        {
            line.ShowDialog();
            Bt_Color_line.BackColor = line.Color;
            panel1.Invalidate();
        }

        private void Bt_Color_fill_Click(object sender, EventArgs e)
        {
            fill_shape.ShowDialog();
            Bt_Color_fill.BackColor = fill_shape.Color;
            panel1.Invalidate();

        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            if (CB_fill.Checked)
            {
                Bt_Color_fill.Enabled = true;
            }
            else
            {
                Bt_Color_fill.Enabled = false;
                //fill_shape.Color= Color.Silver;
                Bt_Color_fill.BackColor = Color.Silver; ;
            }
            panel1.Invalidate();
        }
        private void draw_star(Graphics graphics)
        {
            //Graphics graphics;
            //graphics = panel1.CreateGraphics();
            graphics.Clear(Color.White);
            int x_0 = panel1.Width / 2;
            int y_0 = panel1.Height / 2;
            int sides = Convert.ToInt32(numericUpDown1.Value)*2;
            float size_line = (float)nUpD_line_size.Value;
            PointF[] shape = new PointF[sides];
            
            float r = (Math.Min(panel1.Height,panel1.Width)-16)/2;
            float r1 = r * tB_Scale.Value/1000;
            for (int i = 0; i < sides; i++)
            {
                if(i%2==0)
                {
                    shape[i] = new PointF(
                    x_0 + r * (float)Math.Cos(i * 360 / sides * Math.PI / 180f),
                    y_0 + r * (float)Math.Sin(i * 360 / sides * Math.PI / 180f));
                }
                else
                {
                    shape[i] = new PointF(
                    x_0 + r1 * (float)Math.Cos(i * 360 / sides * Math.PI / 180f),
                    y_0 + r1 * (float)Math.Sin(i * 360 / sides * Math.PI / 180f));
                }
                
            }
            if(CB_fill.Checked==true)
            {
                graphics.FillPolygon(new SolidBrush(fill_shape.Color), shape);
            }
            graphics.DrawPolygon(new Pen(line.Color,size_line), shape);
        }

        private void numericUpDown1_ValueChanged(object sender, EventArgs e)
        {
            panel1.Invalidate();
        }

        private void Form1_Resize(object sender, EventArgs e)
        {
            panel1.Invalidate();
        }

        private void tB_Scale_Scroll(object sender, EventArgs e)
        {
            panel1.Invalidate();
        }

        private void nUpD_line_size_ValueChanged(object sender, EventArgs e)
        {
            panel1.Invalidate();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            //draw_star();
            timer1.Stop();
        }
    }
}

 

komentarz 22 lipca 2018 przez profesorek96 Szeryf (91,420 p.)
Co to znaczy modyfikować przez refleksje ?
komentarz 24 lipca 2018 przez Qwerty96 Stary wyjadacz (13,580 p.)
komentarz 24 lipca 2018 przez profesorek96 Szeryf (91,420 p.)
Dzięki wielkie za pomoc.
0 głosów
odpowiedź 20 lipca 2018 przez areklipno Stary wyjadacz (11,990 p.)
Może będą banały, ale czasem tu tkwi przyczyna:

- czy panel jest podpięty do okna?

- czy panel jest widoczny?

- czy w momencie rysowania okno jest widoczne?
komentarz 20 lipca 2018 przez profesorek96 Szeryf (91,420 p.)

Podobne pytania

0 głosów
0 odpowiedzi 673 wizyt
pytanie zadane 19 maja 2023 w C# przez mateusz45 Gaduła (3,300 p.)
+1 głos
1 odpowiedź 398 wizyt
pytanie zadane 26 stycznia 2022 w C# przez mateusz45 Gaduła (3,300 p.)
+1 głos
1 odpowiedź 684 wizyt
pytanie zadane 10 października 2021 w C# przez mateusz45 Gaduła (3,300 p.)

93,740 zapytań

142,675 odpowiedzi

323,294 komentarzy

63,319 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Twierdza Linux. Bezpieczeństwo dla dociekliwych

Aby uzyskać rabat -10%, użyjcie kodu pasja-linux, wpisując go w specjalne pole w koszyku.

...