I'm trying to make a custom control, to show some data from a SQL source. The data should change in a method, which is triggered by a Timer control.
Let say, if I append all my needed data in stringbuffer and then I show this in long label is working. Every time label is repainted, there is no blinking.
But, if I want make more fancy look, I found only way to put controls in FLowLayoutPanel and build whole structure. Ok, it works, but every time the controls are drawn, I need to dispose them. If not, controls being added to infinity, and buffer overload.
But If I dispose() or clear() them, there is blinking every time controls are redrawn.
Is there a way to get rid of this blinking? Or maybe some other way to do my work?
My code:
void timer_Tick(object sender, EventArgs e)
{
try
{
GetMapData();
}
catch (Exception ex)
{
}
}
private void GetMapData()
{
DataSet ds = MapStatistics.GetMapData(top, bottom, left, right, idUnit, idCustomerTmp);
DataTable activDriversForZones = ds.Tables["ActivDriversForZone"];
DataTable zones zones = ds.Tables["Zones"];
if (zones != null || zones.Rows.Count > 0)
{
ClearflpPanel(flpTest2);
zonesDriverCount = 0;
foreach (DataRow rowZones in zones.Rows)
{
string idZone = Convert.ToString(rowZones["id_zone"]);
string title = Convert.ToString(rowZones["title"]);
StringBuilder zoneDriver = new StringBuilder();
Label labelRowZone = new Label();
labelRowZone.Width = 400;
labelRowZone.AutoSize = true;
labelRowZone.Font = new System.Drawing.Font("Arial", 10, FontStyle.Bold);
labelRowZone.Text = (title + ": ");
flpTest2.Controls.Add(labelRowZone);
Label labelRowDriver = new Label();
foreach (DataRow rowDriver in activDriversForZones.Rows)
{
string idUnit = Convert.ToString(rowDriver["id_unit"]);
string imsi = Convert.ToString(rowDriver["imsi"]);
string zoneIn = Convert.ToString(rowDriver["zone_in"]);
if (idZone == zoneIn)
{
zonesDriverCount++;
zoneDriver.Append(imsi + "/" + idUnit + ", ");
labelRowDriver.Text = (zoneDriver.ToString());
}
flpTest2.Controls.Add(labelRowDriver);
}
}
}
}
public void ClearflpPanel(FlowLayoutPanel flp)
{
zonesDriverCount = 0;
List<Control> listControls = flp.Controls.Cast<Control>().ToList();
foreach (Control control in listControls)
{
flpTest2.Controls.Clear();
//flpTest2.Dispose();
}
}
Create a custom flowLayoutPanel class and add this in its constructor
Then do everything the same way you are doing now except you create your flowlayout panel with CustomFLP instead of FlowLayoutPanel.
This adds a double buffer to your control, might not work with a lot of updates.