首先,我的英语不好。 因此,如果存在语法错误,请理解..
我提到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()。
有更好的方法,比如在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();
}
}
答案 0 :(得分:1)
Hans Passant回答说.Invalidate()会更好。
@HansPassant感谢您的帮助!
public float Value
{
get
{
return _tankLevel_Value;
}
set
{
_tankLevel_Value = value;
this.Invalidate();
}
}