我使用OnPaint(c#)事件在我的表单中绘制一些东西。我想在OnPaint过程中获取变量的值。但我不能在OnPaint过程之前或之后得到它......
实际上,变量就像一个我希望增加ProgressBar值的计数器。
我尝试添加一个Thread,一个Timer和“ValueChanged”事件,我仍然无法获得该值。 代码很长(用于从某些数据生成HeatMap)。
我在事件期间增加了一些for循环的值,并通过“Invalidate()”函数调用OnPaint事件。
我希望在不粘贴代码的情况下明确表示(这很长)! 感谢。
使用代码这更好:(简化)
public partial class HeatPainter : UserControl
{
public long _progress = 0; //My counter
public HeatPainter()
{
InitializeComponent();
}
public void DrawHeatMap(List<List<int>> Items, decimal Value, int MaxStacks, int Factor, string FileName)
{
if (_allowPaint) //If the control is ready to process
{
timer1.Start();
_progress = 0;
_allowPaint = false;
Invalidate();
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
for (int Pass = _factor; Pass >= 0; Pass--)
{
//Some draw stuff
//...
_progress++;
}
}
private void timer1_Tick(object sender, EventArgs e)
{
Console.WriteLine(_progress);
}
}
答案 0 :(得分:0)
看起来你的重新粉刷需要花费很多时间。在重新绘制过程中,您无法更改表单上的任何内容(直到结束时才会更改)。
所以你应该从其他角度看待这个任务。如果要在并行线程(或其他并行化构造How to create a jpg image dynamically in memory with .NET?)中创建图像(如http://www.dotnetperls.com/backgroundworker),该怎么办?绘制完成后,您将其设置为背景或某些PictureBox的.Image
。表格将始终响应。
您必须同步(更新进度条),但这不是一项艰巨的任务(Thread not updating progress bar control - C#,C# Windows Forms Application - Updating GUI from another thread AND class?)。
对于未来:Threads和BackgroundWorkers正逐渐远离.NET世界。它们仍然在.NET中使用&lt; 4.0但.NET 4.0及更高版本为异步操作提供了更好的抽象。我建议您阅读Tasks和Async Await。它们更适合于许多启动 - 工作 - 获得结果完成情景。
您应该只使用一个将绘制图像的异步构造(例如BackgroundWorker)。您的用户控件应该提供一个事件(实际上最好从用户界面重构此功能),如
public event EventHandler ProgressChanged;
并在修改Progress
的属性时在创建图像的代码中引发此事件。只是不要忘记同步和调度(见上文)。