I was wondering if there is an easy way to print out any control in C# to a printer. My specific example is trying to print a TableLayoutPanel to a receipt (so i don\'t have
private static void PrintControl(Control control)
{
var bitmap = new Bitmap(control.Width, control.Height);
control.DrawToBitmap(bitmap, new Rectangle(0, 0, control.Width, control.Height));
var pd = new PrintDocument();
pd.PrintPage += (s, e) => e.Graphics.DrawImage(bitmap, 100, 100);
pd.Print();
}
It's still using DrawToBitmap, but it's most elegant you're gonna get.
It is pretty concise, readable and not inefficient, so I don't see any reason not to like it.
I have an answer to my own question that's in a somewhat different direction than I was going before. In WPF, you can draw a control to any surface, so I create a "FlowDocument" object and add "Paragraphs" that contain grids, images, and whatever else I need to display. I'll keep the other answer marked as accepted, but I figured I'd add this in case anyone was interested in the direction I ended up going.
FlowDocument flowDoc = new FlowDocument();
Paragraph header = new Paragraph();
Grid imageGrid = new Grid();
imageGrid.ColumnDefinitions.Add(new ColumnDefinition());
ColumnDefinition colDef = new ColumnDefinition();
colDef.Width = new GridLength(4, GridUnitType.Star);
imageGrid.ColumnDefinitions.Add(colDef);
imageGrid.ColumnDefinitions.Add(new ColumnDefinition());
BitmapImage bitImage = new BitmapImage(new Uri("{...}", UriKind.RelativeOrAbsolute));
Image image = new Image();
image.Source = bitImage;
image.Margin = new Thickness(10.0d);
Grid.SetColumn(image, 1);
imageGrid.Children.Add(image);
header.Inlines.Add(imageGrid);
header.Inlines.Add(new LineBreak());
header.Inlines.Add("Some text here");
header.Inlines.Add(new LineBreak());
flowDoc.Blocks.Add(header);
and there should be plenty of examples on how to print out a FlowDocument, but I can always add more to the example if that's needed.