I´m working on a WinFormsProject, everything works, but when I need to print the invoice, this exception shows up
System.ArgumentException: Parameter is not valid.
at System.Drawing.Graphics.CheckErrorStatus(Int32 status)
at System.Drawing.Graphics.DrawString(String s, Font font, Brush brush, RectangleF layoutRectangle, StringFormat format)
at Panaderia_Supabase.Forms.Cobranza.PrintPage(Object sender, PrintPageEventArgs e) in D:DevNueva carpetaPanaderia-SupabaseFormsCobranza.cs:line 217
This error showed up when I made the method asynchornous, to work with supabase. I checked that all the values are not null. I think the problem is with graphics:
In this method:
public float GetHeight(Graphics graphics)
{
ArgumentNullException.ThrowIfNull(graphics, "graphics");
if (graphics.NativeGraphics == IntPtr.Zero)
{
throw new ArgumentException("graphics");
}
SafeNativeMethods.Gdip.CheckStatus(SafeNativeMethods.Gdip.GdipGetFontHeight(new HandleRef(this, NativeFont), new HandleRef(graphics, graphics.NativeGraphics), out var size));
return size;
}
This is the value when i run the project: graphics.NativeGraphics = 0x0000024f04c04230
And when i try to print the invoice it goes to: graphics.NativeGraphics = 0x0000000000000000
This is my method:
private async void PrintPage(object sender, PrintPageEventArgs e)
{
try
{
// Verifica si el objeto Graphics es válido
if (e.Graphics == null)
{
MessageBox.Show("Objeto Graphics no válido.");
return;
}
Graphics graphics = e.Graphics;
Font font = new("Courier Mono", 10, FontStyle.Regular);
Brush brush = Brushes.Black;
// Generar el ticket
string ticket = await GenerateTicket();
if (string.IsNullOrEmpty(ticket))
{
MessageBox.Show("El ticket no se ha generado correctamente.");
return;
}
float yPos = 10;
float xPos = 10;
float lineHeight = font.Height;
try
{
MessageBox.Show($"Altura de la línea: {lineHeight}");
}
catch (Exception ex)
{
MessageBox.Show($"Error al obtener la altura de la línea: {ex.Message}");
return;
}
try
{
using (StringReader reader = new StringReader(ticket))
{
string line;
while ((line = reader.ReadLine()) != null)
{
if (yPos + lineHeight <= e.MarginBounds.Bottom)
{
try
{
if (string.IsNullOrEmpty(line) || font == null || brush == null || xPos == 0 || yPos == 0)
{
MessageBox.Show($"Valor nulo: line - {line}, font - {font}, brush - {brush} , xPos - {xPos}, yPos - {yPos}");
}
else
graphics.DrawString(line, font, brush, xPos, yPos);
}
catch (Exception ex)
{
MessageBox.Show($"{ex}");
return;
}
yPos += lineHeight;
}
else
{
e.HasMorePages = true;
return;
}
}
}
}
catch (Exception ex)
{
MessageBox.Show($"Error durante el proceso de impresión: {ex.Message}");
}
graphics.Dispose();
font.Dispose();
brush.Dispose();
e.HasMorePages = false;
}
catch (Exception ex)
{
MessageBox.Show($"Error en PrintPage: {ex.Message}");
}
}
If you need some more source code, just ask for it and I´ll provide. Thanks!
I´ve checked nullity of all the parameters, tried to pass fixed values as parameters also doesn´t worked.
And the exceptions messages are not very helpful, so I don´t know what to do.
Lucas Rius is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
5
You can’t use async void
in the PrintPage
handler, because the Graphics
object comes from the caller, and they will print the document and dispose it as soon as you return, which happens at the first await
. So you are going to have to get that value elsewhere before this handler even runs.
Also:
- Do not dispose
e.Graphics
. - Do dispose
font
andbrush
withusing
if you are creating them. You don’t need to if they are the pre-existing system ones, as this is a no-op. - You can also significantly simplify the logic:
- You don’t need so many
try
catch
s, you can use a single one on the outside. - Inverting some of the
if
s means you can remove theelse
s.
- You don’t need so many
font
andbrush
ande.Graphics
aren’t going to benull
, you don’t need to check for that.
private void PrintPage(object sender, PrintPageEventArgs e)
{
try
{
string ticket = GetAlreadyGeneratedTicket(); // you can't use async while using the Graphics
if (string.IsNullOrEmpty(ticket))
{
MessageBox.Show("El ticket no se ha generado correctamente.");
return;
}
Graphics graphics = e.Graphics;
using Font font = new("Courier Mono", 10, FontStyle.Regular);
Brush brush = Brushes.Black;
float yPos = 10;
float xPos = 10;
float lineHeight = font.Height;
MessageBox.Show($"Altura de la línea: {lineHeight}");
using StringReader reader = new StringReader(ticket);
string line;
while ((line = reader.ReadLine()) != null)
{
if (yPos + lineHeight > e.MarginBounds.Bottom)
{
e.HasMorePages = true;
return;
}
if (string.IsNullOrEmpty(line) || xPos == 0 || yPos == 0)
{
MessageBox.Show($"Valor nulo: line - {line}, font - {font}, brush - {brush} , xPos - {xPos}, yPos - {yPos}");
}
else
graphics.DrawString(line, font, brush, xPos, yPos);
yPos += lineHeight;
}
}
catch (Exception ex)
{
MessageBox.Show($"Error durante el proceso de impresión: {ex.Message}");
}
e.HasMorePages = false;
}