Measuring and displaying are different in UWP - c#

I wanted to implement itemsControl printing with page breaks like it's described in the following blog: http://blogs.u2u.be/diederik/post/2013/05/21/Printing-a-XAML-ItemsControl-from-a-Windows-8-Store-app.aspx
The problem is that in Windows 10 it works incorrectly (I added background to show items in itemsControl for debugging):
While 8.1 version works as expected:
Is there any idea what can be wrong? All it does is just adds paragraphs to richtext, measures each item content and then splits it by pages.
Windows 10 sample is here.
Windows 8.1 sample is here.
UPDATE:
More info:
I changed textblock to textbox (wanted to add background to text). It turns out that it works better, but text is cut at the end of the page. It started working on all pages except for the first page in preview (text is single line and not wrapping on the first page for some unknown reasons). It works correctly in printed document. Weird thing is that it works correctly if I close preview and click print again (even though last line on page is still cut).

I have tried your sample code: The problem is that the system default templates for your two applications are not all the same, so that there is a little difference in the display mode for the item. To fix the problem in the win10 app, you'd better define a proper layout style for the control. There are various ways to achieve this: adding a proper template in resources, or defining in code.
Please try following code in the "PreparePrintContent" function. Please notice that I adjust the layout by setting margin of the UIElement. This is a very simple approach just for your reference:
var x = itemsControl.ContainerFromItem(item) as ContentPresenter;
Paragraph p = new Paragraph();
InlineUIContainer c = new InlineUIContainer();
var o = x.ContentTemplate.LoadContent() as UIElement;
(o as FrameworkElement).DataContext = item;
(o as FrameworkElement).Margin = new Thickness(40);

Related

How can I insert an element to the bottom of a specific page in iText7?

I'm exploring different options for .NET PDF libraries. One of my requirements is to place a box at the bottom of the first page and if any of the content reaches the box, it should overflow onto the next page.
For example:
Shown above, paragraph 7 would normally take up some of the space that's occupied by the "reserved" area. Instead, the part that would have taken up that space is shifted to the next page.
That image was achieved using Gembox.Document by adding the box as a footer element that only renders on the first page. However, in iText7, the examples I've seen for adding a footer (such as this one), places the content as a floating element that renders over the existing content and does not affect the layout/flow of the rest of the document.
I also tried adding a paragraph on the PageEnd event handler without the canvas (snippet below), but instead of adding it to the specified page, it's added to the end of the entire document.
public void HandleEvent(Event evt)
{
var docEvent = (PdfDocumentEvent)evt;
var page = docEvent.GetPage();
int pageNum = docEvent.GetDocument().GetPageNumber(page);
if (pageNum == 1)
{
doc.Add(new Paragraph("Testing a thing"));
}
}
Is the type of effect I'm looking for something that I can replicate using iText7?
I believe you can combine the concepts of https://github.com/itext/i7ns-samples/blob/develop/itext/itext.samples/itext/samples/sandbox/acroforms/AddExtraTable.cs and https://github.com/itext/i7ns-samples/blob/develop/itext/itext.samples/itext/samples/sandbox/events/TextFooter.cs to achieve what you need.
The idea is as follows:
reserve place for your box by making iText give the document's renderer less space for the first page
fill this box with a help of iText's end page events
Another option was suggested in How can I insert an element to the bottom of a specific page in iText7? : you can temporary call Document#setBottomMargin , since elements added via Document#add will not be placed on margins. Then, once the first page is layouted, you can set the initial margins again. This option, however, requires understanding of you layout flow, since the margins should be set only after the content of the first page is layouted.
One more suggestion: althouth event functionality is rather flexible and useful, it seems like using a sledgehammer to crack a nut. You need to call Canvas#ShowTextAligned, which could be done without any event handling. So ideally I would prefer to do the following:
handle page's layout area via an extension of DocumentRenderer
Calling Canvas#ShowTextAligned to fill the reserved box.
As you said, you are exploring different .NET PDF libraries. So I would advise PDFFlow library, which does exactly what you need.
If you have a footer, main document flow will take the rest of page area and will be automatically continued at the next page without overlaying footer.
DocumentBuilder.New()
.AddSection()
.AddParagraph("long text")
.ToSection()
.AddFooterToBothPages(40)
.AddParagraph("this a footer set for each page of this section")
.ToDocument()
.Build("result.pdf");
Here is a tutorial with code examples of using headers, footers, left/right repeating areas: AddingRepeatingArea tutorial.
Hope, this will help you :)

Xamarin Forms: Embed symbols in text

I'm currently evaluating Xamarin Forms as an alternative to our webbased HTML applications targeting mobile platforms.
Our applications often use graphical symbols embedded in paragraphs of text.
The desired effect looks like this:
Of course the text also has to be able to freely wrap around, including all the symbols. In HTML this is simply achieved like this:
<p>Sample text with <img src="sample.jpg"> embedded</p>
How can I achieve the same effect using Xamarin Forms? I already looked at FormattedStrings which allow formatting of subparagraphs of Labels, however they do not seem to allow embedding of images.
Also please note that the solution is required to support iOS, Android and Windows Phone 8.1 at least.
Obviously being forced to use a WebView almost defeats the point of moving a HTML5 app to Xamarin!
In the Xamarin Forums a similar question has been asked: https://forums.xamarin.com/discussion/1649/text-with-image
To solve the problem Tomasz Cielecki cooked up some sample code here: https://gist.github.com/Cheesebaron/5034440
He then went onto blog about it here:
http://blog.ostebaronen.dk/2013/02/adding-images-to-textview-and-edittext.html
<snip>
I started out with a super simple sample trying to get an Image shown in a TextView. I googled up some solutions and sure, Spannables allow using ImageSpan inside of them! There were nice samples and such, and I came up with this.
ImageSpan in TextView
//Load up your drawable.
var imageSpan = new ImageSpan(this, Resource.Drawable.Icon);
//Set the text of SpannableString from TextView
var spannableString = new SpannableString(textView.Text);
//Add image at end of string
spannableString.SetSpan(imageSpan, textView.Text.Length-1, textView.Text.Length, 0);
Easy, huh? And you can add loads of other Spans to the Spannable, such as StyleSpan, which you can style your fonts with bold, italic and other styles.
Since that was so easy, I quickly tried to do that with an EditText. It also works just fine...
</snip>
Currently, the only way to have symbols and images within text blocks is to use WebView (https://developer.xamarin.com/guides/xamarin-forms/working-with/webview/)
var browser = new WebView();
var htmlSource = new HtmlWebViewSource ();
htmlSource.Html = #"<html><body>
<h1>Xamarin.Forms</h1>
<p>Welcome to WebView.</p>
</body></html>";
browser.Source = htmlSource;

Windows Phone 8.1 How to programatically create a tile with specified template

I'm trying to figure out how to create programatically a tile with specified template (TileSquare150x150Text03)? I tried to follow these guides link , MSDN
and a few similiar, but wherever I paste < tile> ... < /tile > markup (e.g. in page or app .xaml file) Visual Studio underlines this markup and says that "tile is not supported in a Windows Phone project". I don't need any tile updates or tiles with two sides. Just simple one with specified template, background color/image and filled with my text.
Can someone explain me what I'm doing wrong? Thank you for your help.
Simple! You need to parse your tile template (an XML string) into an XElement object in code:
var template = "<tile>etc</tile>";
var tileXe = XElement.Parse(template);
Either configure the template xml to your liking before this or after (demo is in the article you linked)
then post it to the tile manager
var tileNotification = new TileNotification(tileXe);
TileUpdateManager.CreateTileUpdaterForApplication().Update(tileNotification);
You can do this anywhere in your app as long as this code runs on the UI thread. Also note that there is a limit to how often you can update the tile, last time I checked it was every 15 seconds at most.

Printing Grid Control with multiple elements

I am trying to print a grid control with multiple elements in it.
I am doing this,
PrintDialog printDialog = new PrintDialog();
if (printDialog.ShowDialog() == true)
{
printDialog.PrintVisual(gridReport, "Visit Report");
}
gridReport is my grid name.
As my grid contains a lot of child elements, only a part of it is getting printed and rest is getting chopped.
How should i solve this ?
I had the same problem a month ago. As far as i know .Net print dialog only prints one page and cuts everything beyond that page. If you want to print multi pages you have to write some logic yourself.
I created a bmp file and cut it to multiple pages, added the pages to a list and at the end printed the list of pages.
I found this article very helpful (it has a solution that cuts the bmpwhenever the height of one page is exceeded, so you will also have to implement a similar logic to cut your bmp when the width of a page is exceeded)
http://www.codeproject.com/Articles/339416/Printing-large-WPF-UserControls
i hope this will help.

Scroll into a Adobe Reader using buttons c#

I Have Created a Simple form in which i have added Adobe Reader from toolbox using steps
right click in toolbox - Choose Items
choose COM Components tab and there "Adobe PDF Reader"
Now Drag&Drop the Adobe PDF Reader Control into an UserControl
I have successfully added this, opened up a pdf file also. Now it automatically provides with vertical scrollbars for scrolling through the pdf document.
What i want to achieve is instead of using the given scrollbars or mouse to scroll, i want to use a button to scroll scroll the pdf, So there will be two buttons, One for Scroll Up And the other for scroll down.
I have gone through many forums, pages, etc. Havnt found anythn that i could use.
I have Tried Simulating key presses with
SendKeys.Send("{DOWN}");
But as i press the button, the focus is lost on the adobe reader so it doesnt work
Pls help me... I have spent almost half a day searchin for a solution
given that you have provided only a simple piece of code you have tried, i am going to try offer you a generic solution - where you will need to replace the specified variables:
button names
your web app name
as for first of the focus you need to specify where it will be, something along the lines of:
var pFocus = webapplication.formname.pdf_document.focus();
// or webapplication.focus(pdf_document);
again i am just writing this as an ideal layout as i have said you will need to replace the listed variables for this to work and possibly tweak the focus code as i haven't tested that - the buttons however provided you insert your variable names will work as i have tested these:
var buttonAction = ((IJavaScriptExecutor)webapplication).ExecuteScript("window.scrollTo(0, document.body.scrollHeight - 5)");
var buttonAction_2 = ((IJavaScriptExecutor)webapplication).ExecuteScript("window.scrollTo(0, document.body.scrollHeight 0)");
//button action will scroll to x co-ordinate 0(far left), y co-ordinate( 5px from bottom)
//buttonAction_2 will return you to the very top left of page, you can edit these values to mess around and try different settings.
so altogether it should look somewhat similar to (if you are using a method for the click just insert the code under there:
var pFocus = webapplication.formname.pdf_document.focus();
if (button.click = true)
webapplication = pFocus;
var buttonAction = ((IJavaScriptExecutor)webapplication).ExecuteScript("window.scrollTo(0, document.body.scrollHeight - 5)");
pFocus.execute(buttonAction);
then for button 2
var pFocus = webapplication.formname.pdf_document.focus();
if (button_2.click = true)
webapplication = pFocus;
var buttonAction_2 = ((IJavaScriptExecutor)webapplication).ExecuteScript("window.scrollTo(0, document.body.scrollHeight 0)");
pFocus.execute(buttonAction_2);
hope this helps to some extent.

Categories