I am trying to print tablview in wpf but only problem i am getting it prints only first page (like took a screenshot). not all data when scroll down.
private void Print(Visual v)
{
System.Windows.FrameworkElement e = v as System.Windows.FrameworkElement;
if (e == null)
return;
PrintDialog pd = new PrintDialog();
if (pd.ShowDialog() == true)
{
Transform originalScale = e.LayoutTransform;
System.Printing.PrintCapabilities capabilities = pd.PrintQueue.GetPrintCapabilities(pd.PrintTicket);
double scale = Math.Min(capabilities.PageImageableArea.ExtentWidth / e.ActualWidth, capabilities.PageImageableArea.ExtentHeight /e.ActualHeight);
e.LayoutTransform = new ScaleTransform(scale, scale);
System.Windows.Size sz = new System.Windows.Size(capabilities.PageImageableArea.ExtentWidth, capabilities.PageImageableArea.ExtentHeight);
e.Measure(sz);
e.Arrange(new System.Windows.Rect(new System.Windows.Point(capabilities.PageImageableArea.OriginWidth, capabilities.PageImageableArea.OriginHeight), sz));
pd.PrintTicket.PageOrientation = System.Printing.PageOrientation.Landscape;
pd.PrintVisual(v, "print chart");
e.LayoutTransform = originalScale;
}
}
Related
In C#, I am trying to print an image using PrintDocument class with the below code. The image is of size 1200 px width and 1800 px height. I am trying to print this image in a 4*6 paper using a small zeebra printer. But the program is printing only 4*6 are of the big image. that means it is not adjusting the image to the paper size !
PrintDocument pd = new PrintDocument();
pd.PrintPage += (sender, args) =>
{
Image i = Image.FromFile("C://tesimage.PNG");
Point p = new Point(100, 100);
args.Graphics.DrawImage(i, 10, 10, i.Width, i.Height);
};
pd.Print();
When i print the same image using Window Print (right click and select print, it is scaling automatically to paper size and printing correctly. that means everything came in 4*6 paper.) How do i do the same in my C# program ?
The parameters that you are passing into the DrawImage method should be the size you want the image on the paper rather than the size of the image itself, the DrawImage command will then take care of the scaling for you. Probably the easiest way is to use the following override of the DrawImage command.
args.Graphics.DrawImage(i, args.MarginBounds);
Note: This will skew the image if the proportions of the image are not the same as the rectangle. Some simple math on the size of the image and paper size will allow you to create a new rectangle that fits in the bounds of the paper without skewing the image.
Not to trample on BBoy's already decent answer, but I've done the code that maintains aspect ratio. I took his suggestion, so he should get partial credit here!
PrintDocument pd = new PrintDocument();
pd.DefaultPageSettings.PrinterSettings.PrinterName = "Printer Name";
pd.DefaultPageSettings.Landscape = true; //or false!
pd.PrintPage += (sender, args) =>
{
Image i = Image.FromFile(#"C:\...\...\image.jpg");
Rectangle m = args.MarginBounds;
if ((double)i.Width / (double)i.Height > (double)m.Width / (double)m.Height) // image is wider
{
m.Height = (int)((double)i.Height / (double)i.Width * (double)m.Width);
}
else
{
m.Width = (int)((double)i.Width / (double)i.Height * (double)m.Height);
}
args.Graphics.DrawImage(i, m);
};
pd.Print();
The solution provided by BBoy works fine. But in my case I had to use
e.Graphics.DrawImage(memoryImage, e.PageBounds);
This will print only the form. When I use MarginBounds it prints the entire screen even if the form is smaller than the monitor screen. PageBounds solved that issue. Thanks to BBoy!
You can use my code here
//Print Button Event Handeler
private void btnPrint_Click(object sender, EventArgs e)
{
PrintDocument pd = new PrintDocument();
pd.PrintPage += PrintPage;
//here to select the printer attached to user PC
PrintDialog printDialog1 = new PrintDialog();
printDialog1.Document = pd;
DialogResult result = printDialog1.ShowDialog();
if (result == DialogResult.OK)
{
pd.Print();//this will trigger the Print Event handeler PrintPage
}
}
//The Print Event handeler
private void PrintPage(object o, PrintPageEventArgs e)
{
try
{
if (File.Exists(this.ImagePath))
{
//Load the image from the file
System.Drawing.Image img = System.Drawing.Image.FromFile(#"C:\myimage.jpg");
//Adjust the size of the image to the page to print the full image without loosing any part of it
Rectangle m = e.MarginBounds;
if ((double)img.Width / (double)img.Height > (double)m.Width / (double)m.Height) // image is wider
{
m.Height = (int)((double)img.Height / (double)img.Width * (double)m.Width);
}
else
{
m.Width = (int)((double)img.Width / (double)img.Height * (double)m.Height);
}
e.Graphics.DrawImage(img, m);
}
}
catch (Exception)
{
}
}
Answer:
public void Print(string FileName)
{
StringBuilder logMessage = new StringBuilder();
logMessage.AppendLine(string.Format(CultureInfo.InvariantCulture, "-------------------[ START - {0} - {1} -------------------]", MethodBase.GetCurrentMethod(), DateTime.Now.ToShortDateString()));
logMessage.AppendLine(string.Format(CultureInfo.InvariantCulture, "Parameter: 1: [Name - {0}, Value - {1}", "None]", Convert.ToString("")));
try
{
if (string.IsNullOrWhiteSpace(FileName)) return; // Prevents execution of below statements if filename is not selected.
PrintDocument pd = new PrintDocument();
//Disable the printing document pop-up dialog shown during printing.
PrintController printController = new StandardPrintController();
pd.PrintController = printController;
//For testing only: Hardcoded set paper size to particular paper.
//pd.PrinterSettings.DefaultPageSettings.PaperSize = new PaperSize("Custom 6x4", 720, 478);
//pd.DefaultPageSettings.PaperSize = new PaperSize("Custom 6x4", 720, 478);
pd.DefaultPageSettings.Margins = new Margins(0, 0, 0, 0);
pd.PrinterSettings.DefaultPageSettings.Margins = new Margins(0, 0, 0, 0);
pd.PrintPage += (sndr, args) =>
{
System.Drawing.Image i = System.Drawing.Image.FromFile(FileName);
//Adjust the size of the image to the page to print the full image without loosing any part of the image.
System.Drawing.Rectangle m = args.MarginBounds;
//Logic below maintains Aspect Ratio.
if ((double)i.Width / (double)i.Height > (double)m.Width / (double)m.Height) // image is wider
{
m.Height = (int)((double)i.Height / (double)i.Width * (double)m.Width);
}
else
{
m.Width = (int)((double)i.Width / (double)i.Height * (double)m.Height);
}
//Calculating optimal orientation.
pd.DefaultPageSettings.Landscape = m.Width > m.Height;
//Putting image in center of page.
m.Y = (int)((((System.Drawing.Printing.PrintDocument)(sndr)).DefaultPageSettings.PaperSize.Height - m.Height) / 2);
m.X = (int)((((System.Drawing.Printing.PrintDocument)(sndr)).DefaultPageSettings.PaperSize.Width - m.Width) / 2);
args.Graphics.DrawImage(i, m);
};
pd.Print();
}
catch (Exception ex)
{
log.ErrorFormat("Error : {0}\n By : {1}-{2}", ex.ToString(), this.GetType(), MethodBase.GetCurrentMethod().Name);
}
finally
{
logMessage.AppendLine(string.Format(CultureInfo.InvariantCulture, "-------------------[ END - {0} - {1} -------------------]", MethodBase.GetCurrentMethod().Name, DateTime.Now.ToShortDateString()));
log.Info(logMessage.ToString());
}
}
Agree with TonyM and BBoy - this is the correct answer for original 4*6 printing of label. (args.PageBounds). This worked for me for printing Endicia API service shipping Labels.
private void SubmitResponseToPrinter(ILabelRequestResponse response)
{
PrintDocument pd = new PrintDocument();
pd.PrintPage += (sender, args) =>
{
Image i = Image.FromFile(response.Labels[0].FullPathFileName.Trim());
args.Graphics.DrawImage(i, args.PageBounds);
};
pd.Print();
}
all these answers has the problem, that's always stretching the image to pagesize and cuts off some content at trying this.
Found a little bit easier way.
My own solution only stretch(is this the right word?) if the image is to large, can use multiply copies and pageorientations.
PrintDialog dlg = new PrintDialog();
if (dlg.ShowDialog() == true)
{
BitmapImage bmi = new BitmapImage(new Uri(strPath));
Image img = new Image();
img.Source = bmi;
if (bmi.PixelWidth < dlg.PrintableAreaWidth ||
bmi.PixelHeight < dlg.PrintableAreaHeight)
{
img.Stretch = Stretch.None;
img.Width = bmi.PixelWidth;
img.Height = bmi.PixelHeight;
}
if (dlg.PrintTicket.PageBorderless == PageBorderless.Borderless)
{
img.Margin = new Thickness(0);
}
else
{
img.Margin = new Thickness(48);
}
img.VerticalAlignment = VerticalAlignment.Top;
img.HorizontalAlignment = HorizontalAlignment.Left;
for (int i = 0; i < dlg.PrintTicket.CopyCount; i++)
{
dlg.PrintVisual(img, "Print a Image");
}
}
Hi I am looking to print a StackPanel that contains a listbox which can contain an infinite number of items and therefore needs to print over multiple pages. I found this code online and it works fine.
public static FixedDocument GetFixedDocument(FrameworkElement toPrint, PrintDialog printDialog)
{
if (printDialog == null)
{
printDialog = new PrintDialog();
}
var capabilities = printDialog.PrintQueue.GetPrintCapabilities(printDialog.PrintTicket);
var pageSize = new Size(printDialog.PrintableAreaWidth, printDialog.PrintableAreaHeight);
var visibleSize = new Size(capabilities.PageImageableArea.ExtentWidth, capabilities.PageImageableArea.ExtentHeight);
var fixedDoc = new FixedDocument();
//If the toPrint visual is not displayed on screen we neeed to measure and arrange it
toPrint.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
toPrint.Arrange(new Rect(new Point(0, 0), toPrint.DesiredSize));
//
var size = toPrint.DesiredSize;
//Will assume for simplicity the control fits horizontally on the page
double yOffset = 0;
while (yOffset < size.Height)
{
var vb = new VisualBrush(toPrint)
{
Stretch = Stretch.None,
AlignmentX = AlignmentX.Left,
AlignmentY = AlignmentY.Top,
ViewboxUnits = BrushMappingMode.Absolute,
TileMode = TileMode.None,
Viewbox = new Rect(0, yOffset, visibleSize.Width, visibleSize.Height)
};
var pageContent = new PageContent();
var page = new FixedPage();
((IAddChild)pageContent).AddChild(page);
fixedDoc.Pages.Add(pageContent);
page.Width = pageSize.Width;
page.Height = pageSize.Height;
var canvas = new Canvas();
FixedPage.SetLeft(canvas, capabilities.PageImageableArea.OriginWidth);
FixedPage.SetTop(canvas, capabilities.PageImageableArea.OriginHeight);
canvas.Width = visibleSize.Width;
canvas.Height = visibleSize.Height;
canvas.Background = vb;
page.Children.Add(canvas);
yOffset += visibleSize.Height;
}
return fixedDoc;
}
However this causes certain items of a listbox to be cut off at the bottom of a page and continued on the next page (as shown below). Is it possible to modify this code in any way to determine the size of the page and if the current listboxitem does not fit onto this page that it starts on the next page? Quite new to all this so any help would be greatly appreciated.
I had a similiar task once and came up with this code, which uses a 'dummy' renderer to determine the height of the element up front and then either adds it to the current page or creates a new one. For sure, that's not a very beautiful solution, but it did the job at the time. Maybe you can take sth. away from it.
Size A4Size = new Size(793.92, 1122.24);
Size InfiniteSize = new Size(double.PositiveInfinity, double.PositiveInfinity);
var pages = new List<FrameworkElement>();
int pageNumber = 0;
var printDate = DateTime.Now;
var size = A4Size;
var currentPage = new Report(size, printDate);
currentPage.Render();
var listElements = new Queue<ElementsToPrint>(...);
var dummyRenderer = new Viewbox();
dummyRenderer.Child = currentPage;
dummyRenderer.Measure(InfiniteSize);
dummyRenderer.Arrange(new Rect(dummyRenderer.DesiredSize));
dummyRenderer.UpdateLayout();
var template = (DataTemplate)View.FindResource("ItemTemplate");
dummyRenderer.Child = null;
var availableHeight = currentPage.View.ActualHeight;
while (listElements.Count > 0)
{
var elementToRender = listElements.Dequeue();
dummyRenderer.Child = new ListViewItem()
{
Content = elementToRender,
ContentTemplate = template,
Foreground = Brushes.Black
};
dummyRenderer.Measure(InfiniteSize);
dummyRenderer.Arrange(new Rect(dummyRenderer.DesiredSize));
dummyRenderer.UpdateLayout();
var renderedItem = (ListViewItem)dummyRenderer.Child;
dummyRenderer.Child = null;
var willItFit = availableHeight > renderedItem.ActualHeight;
if (willItFit)
{
currentPage.DataListView.Items.Add(renderedItem);
availableHeight -= renderedItem.ActualHeight;
}
else
{
dummyRenderer.Child = currentPage;
dummyRenderer.Measure(InfiniteSize);
dummyRenderer.Arrange(new Rect(dummyRenderer.DesiredSize));
dummyRenderer.UpdateLayout();
dummyRenderer.Child = null;
pages.Add(currentPage);
// Set up a new Page
pageNumber++;
currentPage = new DiaryReport(size,pageNumber,printDate,anonymous);
dummyRenderer.Child = currentPage;
dummyRenderer.Measure(InfiniteSize);
dummyRenderer.Arrange(new Rect(dummyRenderer.DesiredSize));
dummyRenderer.UpdateLayout();
dummyRenderer.Child = null;
availableHeight = currentPage.DataListView.ActualHeight;
currentPage.DataListView.Items.Add(renderedItem);
availableHeight -= renderedItem.ActualHeight;
}
i have a wpf usercontrol with bellow properties:
Width=170mm(642px)
Height=85mm(321px)
i want to print that on a paper with above size(Width=170mm and Height=85mm)
my problem is:when i print it,some items print out of the paper,i think the paper size if Letter by default,if it is correct,how can i change it to above Width and Height?
my code is bellow:
var p = new myUserControl();
var pDoc = new System.Windows.Controls.PrintDialog();
if (pDoc.ShowDialog().Value)
{
pDoc.PrintVisual(p, "MyPrint");
}
maybe something like this needs(this is a settings for System.Windows.Forms.PrintDialog but i use System.Windows.Controls.PrintDialog that it has no PrinterSettings property):
var printerSettings = new PrinterSettings();
var labelPaperSize = new PaperSize { RawKind = (int)PaperKind.A6, Height = 148, Width = 105 };
printerSettings.DefaultPageSettings.PaperSize = labelPaperSize;
var labelPaperSource = new PaperSource { RawKind = (int)PaperSourceKind.Manual };
printerSettings.DefaultPageSettings.PaperSource = labelPaperSource;
if (printerSettings.CanDuplex)
{
printerSettings.Duplex = Duplex.Default;
}
In WPF 1 unit = 1/96 of inch, so you can calculate your size in inches using this formula
you can set printDlg.PrintTicket.PageMediaSize to the size of the Paper and then transform your window to print in that area as below:
private void _print()
{
PrintDialog printDlg = new System.Windows.Controls.PrintDialog();
PrintTicket pt = printDlg.PrintTicket;
Double printableWidth = pt.PageMediaSize.Width.Value;
Double printableHeight = pt.PageMediaSize.Height.Value;
Double xScale = (printableWidth - xMargin * 2) / printableWidth;
Double yScale = (printableHeight - yMargin * 2) / printableHeight;
this.Transform = new MatrixTransform(xScale, 0, 0, yScale, xMargin, yMargin);
//now print the visual to printer to fit on the one page.
printDlg.PrintVisual(this, "Print Page");
}
I'm not an English user,so forgive me for grammatical problems please. Smile | :)
I have some paper forms that i want to print some labels on them.these papers have special size(24 cm * 14).so I made a panel(907 pixel * 529 pixel) and i put my labels on it(I converted cm to pixel and i put labels in the special parts of my panel).these labels are going to be printed in empty fields of my paper forms.but the problem is that, just the first form can be printed in the right style.others are printed in upper place of the form. I thought it may be because of I didn't give my panel and labels exact size in pixel. but i couldn't give my panel exact size in pixels,coz it doesn't accept pixels in decimal. any ideas?
this is a part of my code:
private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
Pen blackPen = new Pen(Color.Black, 1);
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
e.Graphics.DrawLine(blackPen, 188, 400, 302, 400);
e.Graphics.DrawRectangle(blackPen, 330, 319, 122, 55);
e.Graphics.DrawString(label20.Text, label20.Font, new SolidBrush(label20.ForeColor), label20.Location);
e.Graphics.DrawString(label21.Text, label21.Font, new SolidBrush(label21.ForeColor), label21.Location);
e.Graphics.DrawString(label23.Text, label23.Font, new SolidBrush(label23.ForeColor), label23.Location);
e.Graphics.DrawString(label24.Text, label24.Font, new SolidBrush(label24.ForeColor), label24.Location);
e.Graphics.DrawString(label25.Text, label25.Font, new SolidBrush(label25.ForeColor), label25.Location);
e.Graphics.DrawString(label26.Text, label26.Font, new SolidBrush(label26.ForeColor), label26.Location);
e.Graphics.DrawString(label27.Text, label27.Font, new SolidBrush(label27.ForeColor), label27.Location);
e.Graphics.DrawString(lbl_kod.Text, lbl_kod.Font, new SolidBrush(lbl_kod.ForeColor), lbl_kod.Location);
e.Graphics.DrawString(lbl_ttarikh.Text, lbl_ttarikh.Font, new SolidBrush(lbl_ttarikh.ForeColor), lbl_ttarikh.Location);
e.Graphics.DrawString(lbl_ctot25.Text, lbl_ctot25.Font, new SolidBrush(lbl_ctot25.ForeColor), lbl_ctot25.Location);
e.Graphics.DrawString(lbl_pricetot25.Text, lbl_pricetot25.Font, new SolidBrush(lbl_pricetot25.ForeColor), lbl_pricetot25.Location);
e.Graphics.DrawString(lbl_pricetot.Text, lbl_pricetot.Font, new SolidBrush(lbl_pricetot.ForeColor), lbl_pricetot.Location);
e.Graphics.DrawString(lbl_pricetoth.Text, lbl_pricetoth.Font, new SolidBrush(lbl_pricetoth.ForeColor), lbl_pricetoth.Location);
e.Graphics.DrawString(lbl_name.Text, lbl_name.Font, new SolidBrush(lbl_name.ForeColor), lbl_name.Location);
e.Graphics.DrawString(lbl_dtarikh.Text, lbl_dtarikh.Font, new SolidBrush(lbl_dtarikh.ForeColor), lbl_dtarikh.Location);
}
and the print region for each paper form:
for (int i = 0; i < dataGridView1.RowCount && k < 3878; i++)
{
k = Convert.ToInt32(dataGridView1.Rows[i].Cells[0].Value);
bool found = false;
ctot25 = Convert.ToInt32(dataGridView1.Rows[i].Cells[13].Value);
ctot50 = Convert.ToInt32(dataGridView1.Rows[i].Cells[14].Value);
ctot100 = Convert.ToInt32(dataGridView1.Rows[i].Cells[15].Value);
foreach (object row1 in hoome)
if (row1.ToString() == (dataGridView1.Rows[i].Cells[0].Value).ToString())
{
found = true;
}
if (found == false)
{
if (i > 0 && ctot25 != 0 || ctot50 != 0 || ctot100 != 0)
{
#region tarikh
string date = dataGridView1.Rows[i].Cells[8].Value.ToString();
var aStringBuilder = new StringBuilder(date);
aStringBuilder.Insert(2, "/");
aStringBuilder.Insert(5, "/");
lbl_dtarikh.Text = aStringBuilder.ToString();
lbl_ttarikh.Text = datestringbuilder.ToString();
#endregion
decimal pricetot25;
pricetot25 = ctot25 * price25;
lbl_name.Text = (dataGridView1.Rows[i].Cells[1].Value).ToString();
lbl_kod.Text = (dataGridView1.Rows[i].Cells[0].Value).ToString();
lbl_ctot25.Text = (ctot25).ToString();
lbl_pricetot25.Text = (pricetot25).ToString();
lbl_pricetoth.Text = num2str(pricetot.ToString()) + " ریال" + "//";
#region print
System.Drawing.Printing.PrintDocument doc = new System.Drawing.Printing.PrintDocument();
doc.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(printDocument1_PrintPage);
PrintDialog PrintSettings = new PrintDialog();
PrintSettings.Document = doc;
PageSettings pgsetting = new PageSettings();
doc.Print();
#endregion
}
}
}
here is a link to my screenshot:
my panel
Since your question is a little unclear, I think you better not to add your panel in design layout and create it programmatically. It'd be better if u take a screenshot of your second page.
EDIT:
Try creating labels in your FOR loop. You can drop panel in this way. I hope it works
if (found == false)
{
if (i > 0 && ctot25 != 0 || ctot50 != 0 || ctot100 != 0)
{
//Somthethin
Label lbl_Name = new Label { Location = new Point(50, 50), Text = (dataGridView1.Rows[i].Cells[1].Value).ToString() };
this.Controls.Add(lbl_Name);
//The rest of the codes
}
}
I am new in C# and I am trying to print richTextBox's text into a page with size 58x297 but the text always starts from the middle of the page. I checked the printer properties but I couldn't find anything wrong. My aim is to print the text of my rich text box at the very left and top point of the page. I believe the problem is the initial spacing because of the size of my page that is 58x297 spacing is normal for an A4 page but not for mine.
This is the piece of work that I am trying to make work
private void button1_Click(object sender, EventArgs e)
{
PrintDialog printDialog = new PrintDialog();
PrintDocument documentToPrint = new PrintDocument();
printDialog.Document = documentToPrint;
if (printDialog.ShowDialog() == DialogResult.OK)
{
StringReader reader = new StringReader(richTextBox1.Text);
documentToPrint.OriginAtMargins = false;
documentToPrint.PrintPage += new PrintPageEventHandler(Document_Print);
documentToPrint.Print();
}
}
private void Document_Print(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
StringReader reader = new StringReader(richTextBox1.Text);
float LinesPerPage = 0;
float YPosition = 0;
int Count = 0;
float LeftMargin = e.MarginBounds.Left;
float TopMargin = e.MarginBounds.Top;
string Line = null;
Font PrintFont = this.richTextBox1.Font;
SolidBrush PrintBrush = new SolidBrush(Color.Black);
LinesPerPage = e.MarginBounds.Height / PrintFont.GetHeight(e.Graphics);
while (Count < LinesPerPage && ((Line = reader.ReadLine()) != null))
{
YPosition = LeftMargin + (Count * PrintFont.GetHeight(e.Graphics));
e.Graphics.DrawString(Line, PrintFont, PrintBrush, LeftMargin, YPosition, new StringFormat());
Count++;
}
if (Line != null)
{
e.HasMorePages = true;
}
else
{
e.HasMorePages = false;
}
PrintBrush.Dispose();
}
It would definitely be great if you have any ideas about. Thanks a lot ...