如何刷新属性更改时由GDI +创建的UserControl

时间:2016-02-19 07:13:39

标签: c# .net custom-controls gdi+

首先,我的英语不好。 因此,如果存在语法错误,请理解..

我提到here.

我创建了一个包含2个项目的简单解决方案。第一个项目(类库)包含一个自定义控件,它通过GDI +绘制Tank。第二个项目(windows窗体)是一个测试应用程序。

我想使用Tank作为控件,可以显示通过调用Value Property设置的实时值。我有很多问题需要实现。大多数人都解决了,但是有一个问题。

在第二个项目中,如果我启动Form1 将Timer添加到Form1并设置由random生成的Value属性以显示timer_tick()中的实时值后,我必须在Form1_Paint()中调用tank1.Refresh()。

有两张图片显示了这个问题。 在每张图片中, Left是以相同的方式创建的控件(以相同的方式工作),例如right One,而不是在Form1_Paint()中调用.Refresh()。

picture1

picture2

有更好的方法,比如在timer_tick()中调用Invalidate()而不是在Form_Paint()中调用tank.Refresh吗? 我已经看到一些问题和答案解释了.Invalidate(),. Reffresh(),. Update()或推荐使用事件,但我不知道哪种方式更好。

为什么我在Form1_Paint()中调用Invalidate()时没有重新绘制tank1?

我希望有人了解初学者的痛苦......

这是代码

public class Tank : UserControl
{
    public Tank();

    public float MAX { get; set; }
    public float MIN { get; set; }
    public float Value { get; set; }

    protected override void Dispose(bool disposing);
    protected override void OnPaint(PaintEventArgs e);
}

public partial class Form1 : Form
{
    Random R = new Random();

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Paint(object sender, PaintEventArgs e)
    {
        tank1.Refresh();
        //waterStorageBasin1.Refresh();
    }
    private void button1_Click(object sender, EventArgs e)
    {
        timer1.Start();
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        tank1.Value = (float)(R.NextDouble() * 10);
        waterStorageBasin1.Value = (float)(R.NextDouble() * 10);

        label1.Text = Math.Round(tank1.Value, 2).ToString();
        label2.Text = Math.Round(waterStorageBasin1.Value, 2).ToString();
        //I want this way
        //Invalidate();
    }
}

1 个答案:

答案 0 :(得分:1)

Hans Passant回答说.Invalidate()会更好。
@HansPassant感谢您的帮助!

    public float Value
    {
        get
        {
            return _tankLevel_Value;
        }
        set
        {
            _tankLevel_Value = value;
            this.Invalidate();
        }
    }