Запуск отрисовки

172
01 августа 2018, 17:20

Имеется программа, рисующая спираль по заданному на TrackBar числу витков и масштабу. Хочется сделать так, чтобы спираль рисовалась сразу при загрузке программы (метод DrawSpiral), но она начинает правильно работать только при изменении значений trackBar1_Scroll/trackBar2_Scroll. Ивенты Form1_Load и Form1_Shown тоже не дали своего результата. Если разбирать пошагово, то алгоритм просчитывает координаты всех точек, но почему-то не выводит их самостоятельно в PictureBox.

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    private List<PointF> PointList;
    private Pen redPen = new Pen(Color.Red, 3);
    private int N, x0, y0, k;
    private double H, r, X1, Y1, X2, Y2;
    private void Form1_Shown(object sender, EventArgs e)
    {
        DrawSpiral();
    }
    private void Form1_Load(object sender, EventArgs e)
    {
        PointList = new List<PointF>();
    }
    private void button1_Click(object sender, EventArgs e)
    {
        Graphics g = Graphics.FromHwnd(pictureBox1.Handle);
        PointList.Clear();
        g.Clear(Color.White);
    }
    private void DrawSpiral()
    {
        // спираль: X=R*Cos(t); Y=R*Sin(t); R=t/2; 0<=t<=2*N*Pi 
        Graphics g = Graphics.FromHwnd(pictureBox1.Handle);
        PointList.Clear();
        g.Clear(Color.White);
        CyclePointList();
        g.InterpolationMode = InterpolationMode.HighQualityBicubic;
        g.TranslateTransform(pictureBox1.ClientSize.Width / 2f, pictureBox1.ClientSize.Height / 2f);
        g.DrawCurve(redPen, PointList.ToArray());
    }
    private void CyclePointList()
    {
        H = Math.PI / 50;
        N = trackBar1.Value;
        x0 = 2000;
        y0 = 1500;
        k = trackBar2.Value * 10;
        for (double t = 0; t <= 2 * Math.PI * N; t = t + H)
        {
            r = t / 2;
            X1 = r * Math.Cos(t);
            Y1 = r * Math.Sin(t);
            X2 = r * Math.Cos(t + H);
            Y2 = r * Math.Sin(t + H);
            PointF point = new PointF((float)((x0 + k * X1) - (x0 + k * X2)), (float)((y0 + k * Y1) - (y0 + k * Y2)));
            PointList.Add(point);
        }
    }
    private void trackBar1_Scroll(object sender, EventArgs e)
    {
        label3.Text = trackBar1.Value.ToString();
        DrawSpiral();
    }
    private void trackBar2_Scroll(object sender, EventArgs e)
    {
        label4.Text = trackBar2.Value.ToString();
        DrawSpiral();
    }
}

}

Кроме того, даже если поместить в Form_Shown реализацию метода Graphics.DrawCurve с MSDN, то рисовать он тоже не будет. Соответственно, дело не в алгоритме. В чём заключается проблема?

Состояние формы при ее запуске:

Работа программы при изменении положения TrackBar:

Answer 1

Подпишитесь на событие pictureBox1.Paint, а при изменении значений trackBar перерисовывайте pictureBox.

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        PointList = new List<PointF>();
        pictureBox1.Paint += PictureBox1_Paint;
    }
    private void PictureBox1_Paint(object sender, PaintEventArgs e)
    {
        DrawSpiral(e.Graphics);
    }

    private List<PointF> PointList;
    private Pen redPen = new Pen(Color.Red, 3);
    private int N, x0, y0, k;
    private double H, r, X1, Y1, X2, Y2;

    private void button1_Click(object sender, EventArgs e)
    {
        Graphics g = Graphics.FromHwnd(pictureBox1.Handle);
        PointList.Clear();
        g.Clear(Color.White);
    }
    private void DrawSpiral(Graphics g)
    {
        PointList.Clear();
        g.Clear(Color.White);
        CyclePointList();
        if (PointList.ToArray().Length < 2) return;
        g.InterpolationMode = InterpolationMode.HighQualityBicubic;
        g.TranslateTransform(pictureBox1.ClientSize.Width / 2f, pictureBox1.ClientSize.Height / 2f);
        g.DrawCurve(redPen, PointList.ToArray());
    }
    private void CyclePointList()
    {
        H = Math.PI / 50;
        N = trackBar1.Value;
        x0 = 2000;
        y0 = 1500;
        k = trackBar2.Value * 10;
        for (double t = 0; t <= 2 * Math.PI * N; t = t + H)
        {
            r = t / 2;
            X1 = r * Math.Cos(t);
            Y1 = r * Math.Sin(t);
            X2 = r * Math.Cos(t + H);
            Y2 = r * Math.Sin(t + H);
            PointF point = new PointF((float)((x0 + k * X1) - (x0 + k * X2)), (float)((y0 + k * Y1) - (y0 + k * Y2)));
            PointList.Add(point);
        }
    }
    private void trackBar1_Scroll(object sender, EventArgs e)
    {
        label3.Text = trackBar1.Value.ToString();
        pictureBox1.Invalidate();
    }
    private void trackBar2_Scroll(object sender, EventArgs e)
    {
        label4.Text = trackBar2.Value.ToString();
        pictureBox1.Invalidate();
    }
}
READ ALSO
Не могу получить Ip4

Не могу получить Ip4

Использую

172
Нажать на кнопку с атрибутом data-reactid

Нажать на кнопку с атрибутом data-reactid

На сайте имеются элементы с атрибутом data-reactidВ них, так понимаю, данные подгружаются динамически

158
Binding ActualHeight и ActualWidth контрола в свойство ViewModel

Binding ActualHeight и ActualWidth контрола в свойство ViewModel

Вроде простой вопрос, но застрялТо-есть, есть к примеру Grid1, растянутый на отведенную для него область, как связать его актуальные размеры...

183