Avoid multiple columns in printing FlowDocument - wpf

I am writing code to print from a FlowDocument.
PrintDialog printDialog = new PrintDialog();
bool? result = printDialog.ShowDialog();
if (result == true)
{
FlowDocument fd = new FlowDocument();
fd.Blocks.Add(new Paragraph(new Run(String.Format("Message:\r\n{0}\r\n", txtMessage.Text))));
fd.PageHeight = printDialog.PrintableAreaHeight;
fd.PageWidth = printDialog.PrintableAreaWidth;
printDialog.PrintDocument((fd as IDocumentPaginatorSource).DocumentPaginator, "print test");
}
This code will print multiple columns in one page. How to avoid this?

I figured out. I need to set the ColumnWidth of FlowDocument.
fd.PagePadding = new Thickness(50);
fd.ColumnGap = 0;
fd.ColumnWidth = printDialog.PrintableAreaWidth;

In case, there is no printDialog involved (e.g. Writing a XML-File), this solution worked for me:
.PagePadding = New Thickness(50)
.ColumnGap = 0
.PageWidth = 21 * 96 / 2.54
.PageHeight = 29.7 * 96 / 2.54
.ColumnWidth = .PageWidth - .PagePadding.Left - .PagePadding.Right

Related

How can I open a new WPF windows in second monitor?

I'm trying to open a new WPF Window in a second monitor from a Windows located in the primary monitor. Following what I founded in other threads and discussions I wrote this:
System.Windows.Forms.Screen s1 = System.Windows.Forms.Screen.AllScreens[1];
System.Drawing.Rectangle r1 = s1.WorkingArea;
form.WindowState = System.Windows.WindowState.Normal;
form.WindowStartupLocation = System.Windows.WindowStartupLocation.Manual;
form.Top = r1.Top;
form.Left = r1.Left;
form.Show();
form.WindowState = System.Windows.WindowState.Maximized;
but this code not work: the new window is shown in the primary monitor. How I can resolve this problem? Thanks.
The solution was to use r.X and r.Y instead of r.top and r.left:
System.Windows.Forms.Screen s1 = System.Windows.Forms.Screen.AllScreens[1];
System.Drawing.Rectangle r1 = s1.WorkingArea;
form.WindowState = System.Windows.WindowState.Normal;
form.WindowStartupLocation = System.Windows.WindowStartupLocation.Manual;
form.Top = r1.Y;
form.Left = r1.X;
form.Show();
form.WindowState = System.Windows.WindowState.Maximized;
now it works.

WPF multipage printing for FixedDocument (Visual C# 2010)

I have a question about multipage FixedPage. I have a Grid created programmatically and the Grid exceeds one A4 page. Now I want to print the Grid in several FixedPage with print margin. But on my way, I create the Grid repeatedly and offset the LeftTop point in the fixedPage Arrange function. I meet a problem that I cannot set print margin in fixedPage, because I set the print margin to the fixedPage and then the first page will have print margin and the next pages will be blank.
How do print multipage of FixedDocument for a large grid want to print?
PrintDialog pd = new System.Windows.Controls.PrintDialog();
if (pd.ShowDialog() == false)
{
return;
}
var pageSize = new Size(pd.PrintableAreaWidth, pd.PrintableAreaHeight);
var document = new FixedDocument();
document.DocumentPaginator.PageSize = pageSize;
for (int nPage = 0; nPage < MaxPage; nPage++)
{
Grid tempGrid = LoadControlMotherInit();
tempGrid.Width = GridWidth;
tempGrid.Height = GridActualHeight;
Point leftTop = new Point();
leftTop.X = 10;
leftTop.Y = -nPage * pageSize.Height;
// Create FixedPage
var fixedPage = new FixedPage();
fixedPage.Width = pageSize.Width;
fixedPage.Height = pageSize.Height;
fixedPage.Margin = new Thickness(0, 0, 0, 96);
fixedPage.Children.Add((UIElement)tempGrid);
fixedPage.Measure(pageSize);
fixedPage.Arrange(new Rect(leftTop, pageSize));
fixedPage.UpdateLayout();
// Add page to document
var pageContent = new PageContent();
((System.Windows.Markup.IAddChild)pageContent).AddChild(fixedPage);
document.Pages.Add(pageContent);
}
pd.PrintDocument(document.DocumentPaginator, "My Document");
From looking at your example,
PrintDialog.PrintDocument method takes in a DocumentPaginator, which could come from a multitude of source.
that being said, you can inherit from DocumentPaginator and take control of everything from PageSize, PageCount to the actual DocumentPage being returned.
Imagine your DocumentPage as a sliding window over your UIElement; but instead of sliding your DocumentPage, you slide your UIElement using its RenderTransform.

How to display images one after another on a single page

This is my code , please let me know the solution for it.
var images = (from pd in SvarkWindow.prodlist where pd.Product_name.StartsWith(imgname) select pd.Image).ToList();
BitmapImage b = new BitmapImage();
b.BeginInit();
//b.UriSource = new Uri(images.ElementAtOrDefault(0), UriKind.Relative);
b.UriSource = new Uri("http://portal.liftech.in/presc/" + images.ElementAtOrDefault(0));
b.EndInit();
// ... Get Image reference from sender.
Image img1 = Productimage0 as Image;
img1.Source = b;
I did this in this way.
look at the code.
ImageSource imageSource = new BitmapImage(new Uri("http://portal.liftech.in/presc/" + images.ElementAtOrDefault(0)));
System.Windows.Controls.Image image1 = new System.Windows.Controls.Image();
image1.Source = imageSource;
Grid.SetColumn(image1, 0);//image1 is added to column 0
Grid.SetRow(image1, 0);//row 0
ProductGrid0.Children.Add(image1);

Get a bitmap from a WPF unshown control

I'd like to create a bitmap from a WPF control. I see some examples in this forum (one above all: Render a "not visible" WPF controls to an bitmap image ), but they can render well only if the WPF control is already shown on the screen.
I have to create a control in a model to associate the bitmap result into an his internal bitmap field.
I followed the example into the above thread, but the result was a bitmap with only a part of the content of the control (as if it was not completely rendered).
How perform a complete render before the image render aquisition?
This is my source code:
if( spChart == null){
String s = "<SparrowChart xmlns=\"http://sparrowtoolkit.codeplex.com/wpf\">" +
" <SparrowChart.XAxis>" +
" <LinearXAxis/>" +
" </SparrowChart.XAxis>" +
" <SparrowChart.YAxis>" +
" <LinearYAxis/>" +
" </SparrowChart.YAxis>" +
"</SparrowChart>";
System.IO.StringReader stringReader = new System.IO.StringReader(s);
System.Xml.XmlReader xmlReader;
xmlReader = System.Xml.XmlReader.Create(stringReader);
spChart = (Sparrow.Chart.SparrowChart)System.Windows.Markup.XamlReader.Load(xmlReader);
spChart.XAxes[0].MinValue = 0;
spChart.XAxes[0].MaxValue = 10;
spChart.YAxes[0].MinValue = 0;
spChart.YAxes[0].MaxValue = 10;
spChart.Series.Clear();
} else {
spChart.Series.Clear();
}
List<System.Drawing.PointF> points = new List<System.Drawing.PointF> {new System.Drawing.PointF(3, 7),
new System.Drawing.PointF(5, 2),
new System.Drawing.PointF(8, 4),
new System.Drawing.PointF(4, 6)};
Sparrow.Chart.SeriesBase LS = new Sparrow.Chart.SplineSeries();
foreach(System.Drawing.PointF x in points) {
Sparrow.Chart.DoublePoint newPoint = new Sparrow.Chart.DoublePoint();
newPoint.Data=x.X;
newPoint.Value=x.Y;
}
spChart.Series.Add(LS);
LS = new Sparrow.Chart.ScatterSeries();
foreach(System.Drawing.PointF x in points) {
Sparrow.Chart.DoublePoint newPoint = new Sparrow.Chart.DoublePoint();
newPoint.Data=x.X;
newPoint.Value=x.Y;
}
spChart.Series.Add(LS);
spChart.Measure(new System.Windows.Size(Double.PositiveInfinity, Double.PositiveInfinity));
spChart.Arrange(new System.Windows.Rect(new System.Windows.Size(1000, 1000)));
spChart.UpdateLayout();
RenderTargetBitmap rtb = new RenderTargetBitmap((int)SpChart.ActualWidth, (int)SpChart.ActualHeight, 96, 96, Windows.Media.PixelFormats.Pbgra32);
rtb.Render(spChart);
PngBitmapEncoder png = new PngBitmapEncoder();
png.Frames.Add(BitmapFrame.Create(rtb));
MemoryStream stream = New MemoryStream();
png.Save(stream);
Bitmap tmpBitmap = new Bitmap(Image.FromStream(stream));
bitmapToRender = MyBitmap.Clone();
MyBitmap.Dispose();
Thank you
Lucio
For me, this one works:
Size size = new Size(432, 460);
frameworkElement.Measure(size);
frameworkElement.Arrange(new Rect(new Point(), size));
frameworkElement.UpdateLayout();
RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap((int)frameworkElement.ActualWidth, (int)frameworkElement.ActualHeight, 96, 96, PixelFormats.Pbgra32);
renderTargetBitmap.Render(frameworkElement);
FormatConvertedBitmap monoBitmap = new FormatConvertedBitmap(renderTargetBitmap, PixelFormats.BlackWhite, null, 0);
BmpBitmapEncoder bmpImage = new BmpBitmapEncoder();
bmpImage.Frames.Add(BitmapFrame.Create(monoBitmap));
byte[] bmpData;
using (MemoryStream buffer = new MemoryStream())
{
bmpImage.Save(buffer);
bmpData = buffer.ToArray();
}
Sorry for resulting in monochrome bitmap, that's just what I used. This can simply be converted to any bitmap type as a result.

Convert a Silverlight text to a path

Is there any way to render a Silverlight text to a path or graphics object at runtime? I know this can be done using the design tools, but I want to be able to do this on the fly.
I've seen an example that calls a webservice which uses WPF constructs to convert a WPF FormattedText object to a PathGeometry, but those objects aren't available in Silverlight.
I'm pretty sure this just isn't supported in Silverlight, but thought it was worth asking.
As you suspected, you'd have to do it server-side to convert the text to a PathGeometry which is supported in Silverlight.
What are you trying to achieve?
Here is the code for creating a SilverLight path Geometry dynamically.
or creating a SilverLight path from a string.
Just paste below method in a new class or in existing class and it will be ready to use.
you can find a sample code to use this functions at bottom of the method.
/// Method tested with SilverLight 2.0
// this method will generates path with the data string
public PathGeometry getPathGeometry(string data)
{
PathGeometry pg = new PathGeometry();
PathSegmentCollection psc = new PathSegmentCollection();
PathFigure pf = new PathFigure();
PathFigureCollection pfc = new PathFigureCollection();
data= data.Replace("M "," M").Replace("C "," C").Replace("L "," L");
string[] str = data.Split(' ');
for (int i = 0; i < str.Length; i++)
{
if (str[i].StartsWith("C") || str[i].StartsWith("c"))
{
string[] item = str[i].Split(',');
string[] item1 = str[i + 1].Split(',');
string[] item2 = str[i + 2].Split(',');
BezierSegment bs = new BezierSegment();
bs.Point1 = new Point(double.Parse(item[0].Substring(1)), double.Parse(item[1]));
bs.Point2 = new Point(double.Parse(item1[0]), double.Parse(item1[1]));
bs.Point3 = new Point(double.Parse(item2[0]), double.Parse(item2[1]));
i += 2;
psc.Add(bs);
}
else if (str[i].StartsWith("L") || str[i].StartsWith("l"))
{
string[] item = str[i].Split(',');
LineSegment ls = new LineSegment();
ls.Point = new Point(double.Parse(item[0].Substring(1)), double.Parse(item[1]));
psc.Add(ls);
}
else if (str[i].StartsWith("M") || str[i].StartsWith("m"))
{
string[] item = str[i].Split(',');
pf.StartPoint = new Point(double.Parse(item[0].Substring(1)), double.Parse(item[1]));
}
else if (str[i].StartsWith("z") || str[i].StartsWith("Z"))
{
pf.IsClosed = true;
}
}
pf.Segments = psc;
pfc.Add(pf);
pg.Figures = pfc;
return pg;
}
///// End of Method
Sample Code for calling method
Path path = new Path();
string str = " F1 M 933.291,430.505C 924.367,415.673 923.007,387.822 922.503,370.604C 921.343,331.31 944.994,317.76 975.999,296.994L 949.334,299.957C 938.729,302.545 930.572,309.925 920.255,313.368C 901.85,319.521 886.504,313.062 870.896,303.53C 850.12,290.842 831.457,270.65 815.107,251.462C 806.279,241.101 798.257,221.598 781.986,226.017C 767.327,229.99 760.199,246.869 743.058,244.012C 737.559,227.262 741.368,204.78 739.591,187.029C 738.108,172.136 733.986,158.933 733.996,143.736C 734.003,128.417 734.091,113.088 733.996,97.7689C 733.909,83.5475 730.302,82.6582 716.114,86.0475C 687.558,92.8796 663.68,115.232 634.418,119.337C 622.391,121.028 598.323,121.184 603.745,103.642C 603.745,103.642 547.667,116.478 522.623,101.969L 397.73,43.1915C 374.54,33.5875 352.799,21.5236 330.186,10.7568C 315.067,3.55951 298.84,3.50623 282.684,6.54358C 268.628,9.18353 252.14,8.36884 238.73,13.0222C 227.932,16.7648 225.711,27.0569 220.839,35.6369C 204.622,64.1582 184.474,89.9609 163.49,115.642C 143.3,140.356 124.747,161.949 100.268,182.977C 76.4618,203.437 58.0045,230.722 39.6698,256.062C 27.9845,272.228 10.5298,295.73 5.62447,315.546C 1.21381,333.368 7.65381,345.95 16.7778,360.225C 30.9738,382.42 52.4365,394.917 74.4578,408.658C 108.356,429.826 144.964,432.43 182.619,439.202C 194.226,441.284 201.93,444.466 212.456,450.234C 228.9,459.261 246.18,466.181 262.031,476.002C 277.378,485.518 288.175,498.328 306.771,498.502C 331.423,498.729 342.159,498.364 359.554,517.221C 368.632,527.06 372.859,537.585 380.38,548.114C 395.159,568.82 409.076,590.689 426.295,609.442C 440.326,624.728 467.967,633.601 487.652,636.902C 505.622,639.908 521.979,632.736 535.859,620.806C 545.402,612.606 552.478,602.246 557.978,591.161C 561.915,583.213 564.966,568.085 572.399,564.296C 578.046,561.41 595.117,563.91 601.338,564.312C 612.171,565.009 621.722,568.994 632.552,569.976C 651.071,571.65 654.679,567.992 668.187,558.989C 681.275,550.254 697.746,547.268 711.451,538.109C 733.726,523.208 751.861,501.273 773.035,484.254C 795.099,466.53 815.65,437.337 845.207,434.924C 871.813,432.754 933.291,430.505 933.291,430.505 Z";
path.Data = getPathGeometry(str);

Resources