WebBrowser get page size - c#

When working with WebBrowser on IE 9 and above the property
webBrowser.Document.Body.ScrollRectangle.Size
returns always 250 x 250 as body dimensions.
Therefore I can't come across a way to check the current page size.
How can I check a html page actual size using IE 9 and above?

I've found a solution that seemed to work all the time until now.
I hope it'll help people with the same problem as I do, as you might have figured out in IE 9 or above, the Body element contains the default size for the ScrollRectangle property, however, as I found out, some other elements do contain the ScrollRectangle property with different sizes.
Most certainly that the HTML element contains a correct ScrollRectangle property, but some other elements might contain a ScrollRectangle greater or smaller in size, and sometimes it fits better.
So I've come to a conclusion that checking all the elements for the ScrollRectangle property is the smartest thing to do, here's the script :
int
CurrentWidth
, CurrentHeight
, CurrentMinWidth = WebBrowserOuterPanel.Width
, CurrentMaxWidth = 0
, CurrentMinHeight = WebBrowserOuterPanel.Height
, CurrentMaxHeight = 0;
foreach(HtmlElement webBrowserElement in webBrowser.Document.All)
{
if ((CurrentWidth = Math.Max(webBrowserElement.ClientRectangle.Width, webBrowserElement.ScrollRectangle.Width)) > CurrentMaxWidth)
CurrentMaxWidth = CurrentWidth;
if ((CurrentHeight = Math.Max(webBrowserElement.ClientRectangle.Height, webBrowserElement.ScrollRectangle.Height)) > CurrentMaxHeight)
CurrentMaxHeight = CurrentHeight;
}
webBrowser.Size = new Size (CurrentMaxWidth > CurrentMinWidth ? CurrentMaxWidth : CurrentMinWidth, CurrentMaxHeight > CurrentMinHeight ? CurrentMaxHeight : CurrentMinHeight);
Another way but might be not correct, in idea for implementing
HtmlElement webBrowserElement = webBrowser.Document.Body.FirstChild;
CurrentMaxWidth = Math.Max(webBrowserElement.ClientRectangle.Width, webBrowserElement.ScrollRectangle.Width);
CurrentMaxHeight = Math.Max(webBrowserElement.ClientRectangle.Height, webBrowserElement.ScrollRectangle.Height);

This should get you the window size
webBrowser.Document.Window.Size

Related

Not able to copy specific pages of word document

I am trying to cut specific pages of my word document(.docx), say 2, 4. I am using for loop to traverse as per the page gave splitting it based on ,.Below is the code for the same
if (startEnd.Contains(','))
{
arrSpecificPage = startEnd.Split(',');
for (int i = 0; i < arrSpecificPage.Length; i++)
{
range.Start = doc.GoTo(WdGoToItem.wdGoToPage, WdGoToDirection.wdGoToAbsolute, arrSpecificPage[i]).Start;
range.End = doc.GoTo(WdGoToItem.wdGoToPage, WdGoToDirection.wdGoToAbsolute, arrSpecificPage[i]).End;
range.Copy();
newDocument.Range().Paste();
}
newDocument.SaveAs(outputSplitDocpath);
}
but the issue with this code is that its just copying the last page only to the new document i.e 4 in this case. How to add 2 as well? What's wrong in the code?
Since you always specify the entire document "range" as the target, each time you paste the entire content of the document is replaced.
It's correct that you work with a Range object and not with a selection, but it helps if you think about a Range like a selection. If you select everything (Ctrl+A) then paste, what was selected is replaced by what is pasted. Whatever is assigned to a Range will replace the content of the Range.
The way to solve this is to "collapse" the Range - think of it like pressing the Right-arrow or left-arrow key to "collapse" a selection to its start or end point. In the object model, this is the Collapse method that takes a parameter indicating whether to collapse to the start or end point (see the code below).
Note that I've also changed the code to use document.Content instead of Document.Range. Content is a property that returns the entire body of the document; Rangeis a method that expects a start and end point defining a Range. Using the property is the preferred method for the entire document.
if (startEnd.Contains(','))
{
arrSpecificPage = startEnd.Split(',');
for (int i = 0; i < arrSpecificPage.Length; i++)
{
range.Start = doc.GoTo(WdGoToItem.wdGoToPage, WdGoToDirection.wdGoToAbsolute, arrSpecificPage[i]).Start;
range.End = doc.GoTo(WdGoToItem.wdGoToPage, WdGoToDirection.wdGoToAbsolute, arrSpecificPage[i]).End;
range.Copy();
Word.Range targetRange = newDocument.Content
targetRange.Collapse(Word.WdCollapseDirection.wdCollapseEnd);
targetRange.Paste();
}
newDocument.SaveAs(outputSplitDocpath);
}

EPPlus Excel AddPicture error 'Column number out of bounds'

I have the following code:
The line with 'excelImage' initialization throws the exception: Column number out of bounds.
What is the solution of the problem?
var range2 = worksheet.Cells ["A" + limiter.ToString ()];
range2.Value = tokenGood.id; //Take from JSON-array
worksheet.Row (limiter).Height = 70; //'limiter' is like row iterator
worksheet.Column (1).Width = 10;
Bitmap img = new Bitmap(Image.FromFile (PIC_FILENAME));
OfficeOpenXml.Drawing.ExcelPicture excelImage = worksheet.Drawings.AddPicture ("random_string", img); //Error Line
excelImage.From.Column = 3;
excelImage.From.Row = limiter;
excelImage.SetSize (60, 60);
Workaround for the bug (EPPlus 4.5.3 doesn't check if image resolution exists in: ExcelDrawing.cs,
internal void SetPixelWidth(int pixels, float dpi), line 400).
If image resolution doesn't set, just set it manually. AddPicture will work fine:
if (img.HorizontalResolution == 0 || img.VerticalResolution == 0)
img.SetResolution(96, 96);
var excelImage = worksheet.Drawings.AddPicture("img", img);
This seems to be a bug in current (4.0.5) EPPlus. Even though the current version has been released recently, the backlog of open issues on CodePlex is huge, so I don't see any approaching fixed release...
I solved it by downloading the source, manually correcting 4 rows in EPPlus/Drawing/ExcelDrawingBase.cs and recompiling.
The rows are 513, 515 (both in SetPixelHeight(int, float)) and 540, 542 (in SetPixelWitdh(int, float)).
I changed the occurrences of From.Column or From.Row in those two lines to Math.Max(From.Column, 0) and Math.Max(From.Row, 0).
The problem here is that the From property is an object that has somehow not been properly initialized, and the values of From.Row and From.Column are thus set to int.MinValue - which is not a valid column/row index, as you may guess.
I've been looking for workarounds that don't require to edit the source code, but couldn't find any: hope this helps.

C# Add int numbers to a list while running a loop

I have tried to get the point across in the title as best as I can but basically what I want to do is add certain items to List while running a loop so I don't have to manually put them into an if statement. Let me please show an example so that I can explain properly.
Example :-
What I need is :- the first number would be 500 and that would be in index 0, then i want a loop to add 150 to the last number generated so that the int list would look like this,
index 0 = 500
index 1 = 650
index 2 = 800
index 3 = 950
Do this repeatedly until say the last number will read 2,000,000
Now I believe that this would be simple to run a loop and base it on conditions but I can only seem to figure out to run a loop that will increment the value in 1.
Hope I have explained well enough
Regards,
M
Now I believe that this would be simple to run a loop and base it on
conditions but I can only seem to figure out to run a loop that will
increment the value in 1.
This is not true, you can adjust the increment of the iterator as you wish.
var numbers = new List<int>();
for(int i=500; i<=2000000; i+=150)
{
numbers.Add(i);
}
For further information on this, please have a look here.
Just another implementation:
var result = new List<int>();
var number = 500;
do
{
result.Add(number);
number+= 150;
} while (number <= 2000000);

C# List of List of Lines Index was out of range

I have a problem very much like the one mentioned here:
ArgumentOutOfRangeException Was Unhandled
I believe that contiguousLines[columnNum].Add(...) is what is causing the error because I am indexing with columnNum
List<line> freeLines = new List<line>();
List<List<line>> contiguousLines = new List<List<line>>();
while(freeLines.Count > 0)
{
int columnNum = contiguousLines.Count;
contiguousLines[columnNum].Add(freeLines[0]);
freeLines.RemoveAt(0);
for(int i = 0; i < freeLines.Count; i++)
{
int last = contiguousLines[columnNum].Count;
if(contiguousLines[columnNum][last].upDown(freeLines[i]))
{
contiguousLines[columnNum].Add(freeLines[i]);
freeLines.RemoveAt(i);
i = -1;
}
}
// Further code that pulls individual elements from freeLines and
// is intended to place them into contiguousLines.
}
The function upDown just compares Start and End points of the lines to see if one (freeLines[i]) is the downstream of the other (contiguousLines[columnNum]).
System.ArgumentOutOfRangeException was unhandled
Message=Index was out of range. Must be non-negative and less than the size of
the collection. Parameter name: index
What is the proper syntax when dealing with a List of Lists?
(Note: I don't often program in C# and this project is something I wrote and have working in C++ only to be later informed C# would play better with the rest of the utilities for my job. In C++ I used vectors for my containers, but apparently copy/pasting the logic won't work as there is some nuance of Lists that I am unaware of.)
I suppose it is also possible to just make a ContiguousLine class that holds a list of Lines, then add to a List<ContiguousLine> from freeLines. Even if that were to be a better solution, I am still curious why I can not address a List of Lists of Lines in this way.
int last = contiguousLines[columnNum].Count;
As lists are 0-indexed, you're 1 over.
you need to add a List first before access the column
contiguousLines.Add(new List<line>());
contiguousLines[columnNum].Add(freeLines[0]);

Get all item's in a category?

I only get 100 results. Code excerpt:
FindingServicePortTypeClient client = FindingServiceClientFactory.getServiceClient(config);
FindItemsByCategoryRequest req = new FindItemsByCategoryRequest();
req.categoryId = new string[] { "1249" };
req.sortOrder = SortOrderType.BestMatch;
req.sortOrderSpecified = true;
req.itemFilter = new ItemFilter[]
{
new ItemFilter()
{
name = ItemFilterType.EndTimeFrom,
value = new string[]
{
DateTime.Now.Add(TimeSpan.FromHours(1)).ToString("yyyy-MM-ddTHH:mm:ss")
}
}
};
PaginationInput pi = new PaginationInput();
pi.entriesPerPage = int.MaxValue;
pi.entriesPerPageSpecified = true;
req.paginationInput = pi;
FindItemsByCategoryResponse response = client.findItemsByCategory(req);
As you can see I tried using int.MaxValue, but to no avail. Is it not possible to get all items from a category?
Well first-off eBay will limit your pagination input entries per page to 100, and your total items returned to 10,000 on any particular search (see http://developer.ebay.com/Devzone/finding/CallRef/findItemsByCategory.html#Request.paginationInput). So this won't work whether it's logical or not. Think of the immense server load they would have to deal with if you could return a result of 100,000+ items in one call.
Now, you might think there's still a clever way to get past the block of limits and just stay under the quantified limits. But according to http://developer.ebay.com/Devzone/finding/CallRef/findItemsByCategory.html#Request.paginationInput.pageNumber (2 entries below the first link) you can't even access results past the 100th page. So at 100 results per page and 100 pages you really only can get any of the first 10,000 (point being that you can not start at page 101, because it's simply disallowed). Again, this is probably because of the resources it would take them to access past that point. This must be somewhat disappointing...
Sorry about that :/, but it's the full story.

Categories

Resources