No code posted, so not sure what you are doing exactly...'
I have not used Winform on Linux with mono.
You could try suspend/resume when updating the label:
Label1.SuspendLayout();
Label1.Text = "new text here";
Label1.ResumeLayout();
or, this may or may not work on Linux:
public static class ControlsExtension
{
public static void SetDoubleBuffered(this Control control, bool doubleBuffered = true)
{
control
.GetType()
.GetProperty("DoubleBuffered", System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.NonPublic)
?.SetValue(control, doubleBuffered, null);
}
}
UPDATE
As mentioned below, the alternative that I would use is a
PictureBox
control and draw directly on it.
Here is how I would do it:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.Resize += Form1_Resize;
Canvas.Paint += Canvas_Paint;
Canvas.MouseClick += Canvas_MouseClick;
Canvas.SetDoubleBuffered();
Canvas.BackColor = Color.Gray;
Canvas.BorderStyle = BorderStyle.FixedSingle;
Canvas.Cursor = Cursors.Hand;
}
private bool showCells = true;
private record Cell(int Row, int Column, string Text, bool Visible = true);
private readonly List<Cell> cells = new();
private readonly float cellWidth = 50f;
private readonly float cellHeight = 50f;
private readonly Font cellFont = new Font( "Time New Roman", 8, FontStyle.Bold );
private readonly StringFormat cellTextFormat = new StringFormat()
{
LineAlignment = StringAlignment.Center,
Alignment = StringAlignment.Center
};
private readonly Color cellBackColor = Color.White;
private readonly Color cellForeColor = Color.Black;
private readonly Color cellBorderColor = Color.Black;
private void Form1_Resize(object? sender, EventArgs e)
{
}
private void Canvas_MouseClick(object? sender, MouseEventArgs e)
{
if (showCells)
labSelected.Text = $@"{Math.Floor(e.X / cellWidth):N0},{Math.Floor(e.Y / cellHeight):N0}";
}
private void Canvas_Paint(object? sender, PaintEventArgs e)
{
Graphics gr = e.Graphics;
foreach (Cell cell in cells)
{
RectangleF rect = new RectangleF(cell.Column * cellWidth,
cell.Row * cellHeight,
cellWidth,
cellHeight);
using SolidBrush backBrush = new SolidBrush(cellBackColor);
gr.FillRectangle(backBrush, rect);
if (!showCells)
continue;
using Pen pen = new Pen(cellBorderColor, 1);
pen.Alignment = PenAlignment.Outset;
gr.DrawRectangle(pen, rect);
using SolidBrush foreBrush = new SolidBrush(cellForeColor);
gr.DrawString(cell.Text, cellFont, foreBrush, rect,
cellTextFormat);
}
}
private void OnAddClick(object sender, EventArgs e)
{
cells.Clear();
FillCells();
showCells = true;
Canvas.Invalidate();
}
private void OnShowClick(object sender, EventArgs e)
{
if (showCells) return;
showCells = true;
Canvas.Invalidate();
}
private void OnHideClick(object sender, EventArgs e)
{
if (!showCells) return;
showCells = false;
Canvas.Invalidate();
labSelected.Text = "None";
}
void FillCells()
{
int nLabelNum = 10;
for (int j = 0; j < nLabelNum; j++)
for (int i = 0; i < nLabelNum; i++)
cells.Add(new Cell(j, i, $"{i} | {j}"));
}
}
NOTES:
*
Canvas
is a
PictureBox
control.
* I am using the
SetDoubleBuffered()
extension method from above.
* I have added a
Canvas_MouseClick to show how to get the selected cell.
Now the rendering is very performant and no flickering or rendering of cells is visible.