Align Page Number to Right Corner in MigraDoc - c#

I know how to show page numbers and how to align them in footer. However my problem is that my Footer contains some custom text which should be left aligned and page number should be aligned to right corner.
string footer = "My custom footer";
Paragraph footerParagraph = section.Footers.Primary.AddParagraph(footer);
footerParagraph.AddTab();
footerParagraph.AddPageField();
Above will generate "My custom footer 1" for page 1, I need page nmuber to be right at the right most corner of the page. I can add extra spaces or tab but thought there must be a clean way to achieve this. Thanks.

Keep it Simple: Use a Tab Stop
The best way to do this is the same as you would do in most word processing tools: with a right-aligned tab-stop, placed on the right margin of the page. This is pretty straight forward, but I couldn't find the "full" solution anywhere, so here's what you need:
// Grab the current section, and other settings
var section = documentWrapper.CurrentSection;
var footer = section.Footers.Primary;
var reportMeta = documentWrapper.AdminReport.ReportMeta;
// Format, then add the report date to the footer
var footerDate = string.Format("{0:MM/dd/yyyy}", reportMeta.ReportDate);
var footerP = footer.AddParagraph(footerDate);
// Add "Page X of Y" on the next tab stop.
footerP.AddTab();
footerP.AddText("Page ");
footerP.AddPageField();
footerP.AddText(" of ");
footerP.AddNumPagesField();
// The tab stop will need to be on the right edge of the page, just inside the margin
// We need to figure out where that is
var tabStopPosition =
documentWrapper.CurrentPageWidth
- section.PageSetup.LeftMargin
- section.PageSetup.RightMargin;
// Clear all existing tab stops, and add our calculated tab stop, on the right
footerP.Format.TabStops.ClearAll();
footerP.Format.TabStops.AddTabStop(tabStopPosition, TabAlignment.Right);
The hardest part of this, is figuring out what your tab stop position should be. Because I'm boring and really like encapsulation, I dynamically calculate the tab stop position, based on the page width, less the horizontal page margins. However, getting the current page width wasn't as easy as I'd thought it'd be, because I'm using PageFormat to set the page dimensions.
Next Challenge: Getting Your Page Width, Dynamically
First, I really hate having tightly coupled code (think: fan-in and fan-out), so even though I know at this point in time what my page width is, even to the point of hard-coding it, I still want to hard code it in only a single place, then refer to that one place everywhere else.
I keep a custom "has-a"/wrapper class to keep this stuff encapsulated into; That's documentWrapper in my code here. Additionally, I don't expose any of the PDFSharp/MigraDoc types to the rest of my application, so I'm using ReportMeta as a way to communicate settings.
Now for some code. When I setup the section, I'm using the MigraDoc PageFormat to define the size of my page for the current section:
// Create, and set the new section
var section = documentWrapper.CurrentDocument.AddSection();
documentWrapper.CurrentSection = section;
// Some basic setup
section.PageSetup.PageFormat = PageFormat.Letter; // Here's my little bit of hard-coding
Unit pageWidth, pageHeight;
PageSetup.GetPageSize(PageFormat.Letter, out pageWidth, out pageHeight);
var reportMeta = documentWrapper.AdminReport.ReportMeta;
if (reportMeta.PageOrientation == AdminReportMeta.ORIENT_LANDSCAPE)
{
section.PageSetup.Orientation = Orientation.Landscape;
documentWrapper.CurrentPageWidth = pageHeight;
}
else
{
section.PageSetup.Orientation = Orientation.Portrait;
documentWrapper.CurrentPageWidth = pageWidth;
}
What's really important here, is that I'm storing the CurrentPageWidth, this becomes really important when setting up our tab stops. The CurrentPageWidth property, is simply a MigraDoc Unit type. I am able to determine what this is by using MigraDoc's PageSetup.GetPageSize with my chosen PageFormat.

A single tab will do. Create a right-aligned tab at the right-most position.
You can set the tab stops for the footer style (recommended) or for the paragraph.
Code snippet modifying a style:
var style = document.Styles[StyleNames.Footer];
style.ParagraphFormat.TabStops.ClearAll();
style.ParagraphFormat.TabStops.AddTabStop(Unit.FromMillimeter(158), TabAlignment.Right);

You could try something like this:
Paragraph paragraph = new Paragraph();
paragraph.Format.Alignment = ParagraphAlignment.Left;
paragraph.AddText("My custom footer: ");
Paragraph paragraph2 = new Paragraph();
paragraph2.Format.Alignment = ParagraphAlignment.Right;
paragraph2.AddText(" Page # ");
paragraph2.AddPageField();
section.Footers.Primary.Add(paragraph);
section.Footers.Primary.Add(paragraph2);

Related

UltraGrid Filter cell property

Working on a code that was written by someone else. Here are the important parts of the code:
UltraGridColumn col = columns.Add("FolderImage", "Status");
col.Header.Fixed = true;
col.AllowRowFiltering = Infragistics.Win.DefaultableBoolean.False;
There is more code written to specify the behavior of the folder, but it is irrelevant for the example; As of right now, the following result is generated:
As you can see, there is a greyed out "Filter" button, and the pin is missing:
I want it to look like this:
I.e. filter button needs to go in the status column (it just needs to be blank), and the pin button should be enabled. According to the Infragistics manual, the code above should produce the very results I am looking for, but it does not.
To hide the filter operator (the 'A' letter) you need to set FilterOperatorLocation of the column to Hidden. To show the pin of the fixed column you need to set to its header FixedHeaderIndicator to Button (by the way this is default value, so if you did not override it at some other place you may skip this step). Try to use code like this:
col.FilterOperatorLocation = FilterOperatorLocation.Hidden;
col.Header.FixedHeaderIndicator = FixedHeaderIndicator.Button;
For the "A" button in a cell, the following code fixed it:
col.FilterOperatorLocation = FilterOperatorLocation.Hidden;
For the pin, I had to enable the "UsedFixedHeaders" property:
this.gridName.DisplayLayout.UseFixedHeaders = true;

Add hyperlink to a slide in the current PowerPoint

I've been searching for this for hours, but could not find appropriate approach to do so. On MSDN, they suggest using Address and SubAddress to locate a slide in a Presentation, but this failed its purpose.
So my question is, how to add a hyperlink to a slide in the same Presentation?
Finally I've figured it out, and since there's lack of resources, I would like to post my solution.
Interestingly, to add a hyperlink to a slide inside the same presentation, you need to leave Address property blank, and set its SubAddress to be a string in a format: "yourSlideID,yourSlideIndex,yourSlideName".
For example, you want to add a hyperlink to a slide with slide ID 256, slide index 1, slide name "Slide 1", to a shape, do this:
var mouseOnClickAction = shape.ActionSettings[PpMouseActivation.ppMouseClick];
mouseOnClickAction.Action = PpActionType.ppActionNamedSlideShow;
mouseOnClickAction.Hyperlink.Address = null;
mouseOnClickAction.Hyperlink.SubAddress = "256,1,Slide 1";
Hope this helps everybody :D

WPF Print XAML Control

I'm trying to add a Print function to a WPF Project. The user can add and delete text to textbox or other controls at runtime so the size of the xaml control is not fixed. If he clicks the print button i want to figure out the size of the control and print a (if neccessary multipage) document. this is my code so far
public void Print(FrameworkElement element)
{
System.Windows.Controls.PrintDialog printDlg = new System.Windows.Controls.PrintDialog();
if (printDlg.ShowDialog() == true) {
double height = element.ActualHeight;
double width = element.ActualWidth;
Size pageSize = new Size(printDlg.PrintableAreaWidth, printDlg.PrintableAreaHeight);
//element.Measure(pageSize);
//element.Arrange(new Rect(5, 5, pageSize.Width, pageSize.Height));
printDlg.PrintVisual(element, "this is a test");
}
}
My idea is to check the actual height and width of the control. If one of these is larger than the pagesize, I know i have to print multiple pages. I'm not quite sure how to do that, but i think i will have to make use of XPSDocument class. Can someone please help me, I dont know how I can split my document into multiple pages and print them and can someone also tell me how to create a FlowDocument from my xaml code.
thanks in advance!
By default, you can't print control on multiple pages, but you can do it manually.
Here's the GREAT article, which solves your problem:
http://www.codeproject.com/Articles/164033/WPF-Visual-Print-Component

get current visible part of page displayed in IE

I'm working on a screen reader and till now I was successful to get the whole text of a page in IE. But I have no idea how to get the current visible part of page or to get the current paragraph that is under the cursor in IE.
I don't mean to give me the code, but just to recommend me if there is a way to do it using APIs or similar things.
from what I found I think it’s not doable using Accessibility APIs.
I GREATLY appreciate any ideas and helps.
If you're application is a WinForms app, you might want to look into using the Browser control. I'm still a bit unclear about what you're looking for, but I think the browser control is what you'll need.
Here's a similar question that may point you in the right direction:
C# WebBrowser control -- Get Document Elements After AJAX?
To access the contents of a paragraph when the cursor moves over it you could use javascript:
var oP = document.body.getElementsByTagName('p');
for (var i = 0; i < oP.length; i++) {
oP[i].onmouseover = function() {
var content = oP[i].innerHTML;
// Do whatever you want with content.
};
}
This will fire the onMouseOver event when cursor moves over a paragraph and you will then be able to read it's content.

Show more/less without stripping Html tags in JavaScript/jQuery

I want to implement readmore/less feature. i.e I will be having html content and I am going to show first few characters from that content and there will be a read more link in front of it. I am currently using this code :
var txtToHide= input.substring(length);
var textToShow= input.substring(0, length);
var html = textToShow+ '<span class="readmore"> … </span>'
+ ('<span class="readmore">' + txtToHide+ '</span>');
html = html + '<a id="read-more" title="More" href="#">More</a>';
Above input is the input string and length is the length of string to be displayed initially.
There is an issue with this code, suppose if I want to strip 20 characters from this string:
"Hello <a href='#'>test</a> output", the html tags are coming between and it will mess up the page if strip it partially. What I want here is that if html tags are falling between the range it should cover the full tag i.e I need the output here to be "Hello <a href='#'>test</a>" . How can I do this
Instead of doing too much manually, I prefer you to go with following jQuery plugin.
http://plugins.learningjquery.com/expander/index.html#getting-started
It will expand and collapse your text for Read more options, Also provide you much customization.
Hope this will help.
Thanks!
Hussain
This will be quite hard since HTML is not a regular language, so using regular expressions would be cumbersome.
Really want you need to do is parse the HTML into a DOM structure using jQuery $('html text') and then recursively go through the elements getting the length of each elements text using .text() and when you come to an element with causes the cumulative text length thus far to be over the limit, split this elements text at that point and set it the element's text to be the left of the split.
Then keep all elements before this one, and disregard all siblings etc that occur after this element. However I have no idea how to implement that simply.
On the other hand you could just strip the HTML tags away, why bother.
If you have the text in a dom element, you could use the innerText/textContent property of the dom element to get just the text without the tags. substring of this text could be used without worrying about the tags.
var post_dom = document.getElementById('#post-content');
var input = post_dom.innerText || post_dom.textContent;
I think the best solution here would be to use
var textToHide = input;
var textToShow = $("<div/>").html(input).text().substring(0, length);
which will convert your HTML to plain text and extract the first few characters for the summary. Then toggle between them when they click the ellipsis rather than trying to display both at the same time.
maybe you could rethink the problem : instead of modifying your text, you could modify the way it is shown on the page.
Say if you want to show only 3 rows of the content, you could modify the content's container style to a height equal to the height of one content row * 3.
Anyway, this could be easily implemented in jquery ,and if you take advantage of it's animate function, you could easily make your own plugin such as :
(function($){
$.fn.lessDetails = function(desiredHeight){
var desiredHeight = desiredHeight || 20; //or any other "default" value
return this.each(function(i){
$(this).realHeight = $(this).css("height");
$(this).css('height',desiredHeight);//or you could animate it
});
};
$.fn.moreDetails = function(){
return this.each(function(i){
$(this).css('height',$(this).realHeight || "auto");//or you could animate it
});
};
})(jQuery);
and then you could call :
$('.less').lessDetails(); $('.showMore').click(function(){$('#'+$(this).attr('rel')).moreDetails();});'
having your html structured as :
< div class="container"> < div id="1" class="less">content goes here </div> < a href="#" rel="1" class="showMore"> show more</a> </ div >
Haven't tested it ,but it should work, or at least should give you a basic idea of my solution.

Categories

Resources