Problems having content in webbrowser scale automatically in Windows Form Application - c#

I'm trying to create a program which scrolls through files located on my computer and displays the files. This is working for me so far but I'm getting content in actual size so the webbrowser adds a scrollbar(obviously). I want the content to scale automatically so it fits in the webbrowser without having to scroll.
Code:
WebBrowser web = new WebBrowser();
System.Drawing.Rectangle workingRectangle = Screen.PrimaryScreen.WorkingArea;
int heightWebcontrol = workingRectangle.Height / 100 * 85;
int widthwebControl = workingRectangle.Width / 100 * 75;
web.Size = new Size(widthwebControl, heightWebcontrol);
web.Location = new Point(0, 0);
web.Navigate(fileName);
this.Controls.Add(web);
Large image in webbrowser, this is just 1/5th of the image:
So basicly, this large image, needs automatically to be scales so it fits the browser exactly.
Thanks guys.

As an option, you can handle DocumentCompleted event of the WebBrowser control and set the style of image based on the size.
For example:
1) Create a Windows Forms Project
2) Open Form1 in desgn mode and drop a WebBrowser control on it.
3) Double click on title-bar of form to handle Load event of the form and use following code:
private void Form1_Load(object sender, EventArgs e)
{
this.webBrowser1.Navigate("https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png");
}
4) Double click on WebBrowser control to handle its DocumentCompleed event and use following code:
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
webBrowser1.Document.Body.SetAttribute("scroll", "no");
var img = webBrowser1.Document.GetElementsByTagName("img")
.Cast<HtmlElement>().FirstOrDefault();
var w = img.ClientRectangle.Width;
var h = img.ClientRectangle.Height;
img.Style = string.Format("{0}: 100%", w > h ? "Width" : "Height");
}
You will see following result, while the original image size is 544x184:
Note 1
This is just an example of what you can do. You can make the decision more intelligent, for example check if the image size is less than the browser size, then you don't need to apply any scaling.
Note 2 - (This is my choice)
If you setup WebBrowser control to support showing modern content the better style for the image will be:
img.Style = "max-width:100%;max-height:100%";
This way, the image will be fit in the browser when it's larger than browser. Also it will not resize when the browser is large enough.

Related

WebView rendering flickers

I'm working on an UWP project and I want to load a WebView with opacity = 0.01f, and only set opacity to 1.0f when WebView_LoadCompleted is called. Until then it is presented by a preview image. But when I'm showing it, it flickers white in like 1 on 20 cases, and I'm testing the same WebView content.
My code looks like this:
Grid grid = new Grid();
//set previewImage as preview of grid content
Image backgroundImage = new Image();
backgroundImage.Source = new BitmapImage(new Uri(#"ms-appdata:///local/" + "some path"));
grid.Children.Add(backgroundImage);
grid.SetValue(Grid.RowProperty, slide.Pos.Y);
grid.SetValue(Grid.ColumnProperty, slide.Pos.X);
MainGrid.Children.Add(grid);
WebView webView = new WebView();
webView.NavigationStarting += WebView_NavigationStarting;
webView.LoadCompleted += WebView_LoadCompleted;
webView.ScriptNotify += WebView_ScriptNotify;
webView.Opacity = 0.01f;
Uri navigationUri = "some local file Uri");
webView.NavigateToLocalStreamUri(navigationUri, myResolver); // myResolver checks if source is allowed to load
webView.Width = 1024;
webView.Height = 768;
Viewbox viewBox = new Viewbox();
viewBox.Stretch = Stretch.Uniform;
viewBox.Child = webView;
grid.Children.Add(viewBox);
And my WebView_LoadCompleted looks like this:
private void WebView_LoadCompleted(object sender, NavigationEventArgs e)
{
WebView webView = (WebView)sender;
webView.Opacity = 1.0f;
}
I was expecting that the WebView will only render its laoded content right away because it is visible (with low opicity) in the ViewBox, and most of the times it is not flickering, but it still appears.
Trying to get a call after WebView_LoadCompleted didn't work yet, I tried some calls like x_LayoutUpdated, x_SizeChanged for the WebView and the ViewBox, but WebView_LoadCompleted is the last called function that runs into a breakpoint.
Setting the WebView.DefaultBackgroundColor to transparent didn't work, it still flickers white.
Placing the WebView below the Image and getting it to the front after a delay for layout time didn't work.
Thanks for your help! I appreciate it!
It looks like there is no proper way to validate that the webview is finished with all possible loading and rendering processes for the webview.
But you can use this answer of another question for other UIElements:
Answer

Click on image and show message box depending on the clicked place

I have this idea of this world map image and when I click a country on it, it shows information of that country in a MessageBox for example does anyone have an idea how to do that?
I have a rectangle and a button and when i click the button it shows the image in the rectangle but i thought if i use polygons to shape the country's but I'm a little stuck.
I would like to have every country apart and maybe that the borders light up when clicked
You can do this pretty easily using WPF:
Find a nice World Map in SVG format. I used this one from Wikipedia:
Download and install Inkscape then open the SVG you've just downloaded. Inkscape has a nice feature that makes it possible to save an SVG as a XAML.
Import the ViewBox from the XAML file into your WPF window/etc:
For each Path in the XAML you can add a MouseEnter/MouseLeave event handler or you can use the same one for all the Paths
Sample code:
private void CountryMouseEnter(object sender, MouseEventArgs e)
{
var path = sender as Path;
if (path != null)
{
path.Fill = new SolidColorBrush(Colors.Aqua);
}
}
private void Country_MouseLeave(object sender, MouseEventArgs e)
{
var path = sender as Path;
if (path != null)
{
path.Fill = new SolidColorBrush(Colors.Black);
}
}
Now it's just a matter of changing colors/showing MessageBoxes etc.
GitHub
My first thought: You could bind a command to the view that will be triggered by a click on a position. If you're using WPF you can bind command parameters to the command to get the x and y of your click...
After that you have to handle the content of your messagebox and the highlighting of the borders depending on the position xy.
have fun :D
Option 1
There is a project on Code Project that someone created that defines hotspots that are clickable with events. You could use that to overlay your map and define the hotspots where you need them.
C# Windows Forms ImageMap Control
Option 2
You could bind to the MouseUp Event on the Image and use the following to see if it is in a Rectangle
private void mapMouseUp(object sender, MouseEventArgs e) {
Rectangle rect1 = new Rectangle(0, 0, 100, 100);
Rectangle rect2 = new Rectangle(0, 100, 100, 100);
if (rect1.Contains(e.Location)) {
// Do your stuff
} else if (rect2.Contains(e.Location)) {
// Do your stuff
}
}

Print preview issue in Steema Teechart with graphics3d

I am using tchart with graphics 3d for real time chart plotting. whenever I try to call print preview for the chart, the preview page is just a blank page and the actual chart background becomes black. I tried different tricks and i found this printpreview works in normal canvas. but as soon as i write the line
Chart1.Graphics3D = new Graphics3DDirect2D(Chart1.Chart);
print preview does not work .
If I call export function, e.g. export to pdf functionality then the pdf file has exported chart in it and alternate route can be I can print the pdf.
But I want to use print preview and give user a functionality to change margins and other things as per their need.
Link for the demo project is http://www.filedropper.com/sampleprojecttchartprint
Link for the Video describing issue is http://tinypic.com/r/2ufg7f5/5
What am I doing wrong here?
There is a limitation with the wrapper TeeChart uses, a limitation documented here:
http://bugs.teechart.net/show_bug.cgi?id=356
As suggested, the workaround is to use the GDI+ canvas for image exportation, e.g.
private void InitializeChart()
{
tChart1.Graphics3D = new Graphics3DDirect2D(tChart1.Chart);
tChart1.Aspect.View3D = false;
FastLine series = new FastLine(tChart1.Chart);
series.FillSampleValues(1000);
}
TChart tChart2;
private void button1_Click(object sender, EventArgs e)
{
if(tChart2 == null) tChart2 = new TChart();
MemoryStream ms = new MemoryStream();
tChart1.Export.Template.Save(ms);
ms.Position = 0;
tChart2.Import.Template.Load(ms);
tChart2.Export.Image.PNG.Width = tChart1.Width;
tChart2.Export.Image.PNG.Height = tChart1.Height;
tChart2.Export.Image.PNG.Save(#"C:\tmp\direct2d.png");
}

Stretch tab headers instead of tab pages in tab control when resizing

I am owner-drawing a left-oriented tabcontrol in winforms.
Each tabpage has a fixed size, so when the UI is stretched wide, I would like the ItemSize width of the tab headers to increase correspondingly.
private void tbcTests_Resize( object sender, EventArgs e )
{
tbcTests.ItemSize = new Size(
tbcTests.Width - tbcTests.TabPages[0].Controls[0].Width - tbcTests.Padding.X,
tbcTests.ItemSize.Height );
}
This code results in a stack overflow. I suspect this is because the resize is done using incorrect dimensions, forcing the control to continuously redraw. However, I am unsure how to fix it. Am I not accounting for excess space correctly?
How should I resize the tab headers and using what dimensions?
Changing the ItemSize property cause the Resize event to fire again. You'll need a helper variable to suppress the nested event. Like this:
private bool busySizing;
private void tbcTests_Resize( object sender, EventArgs e )
{
if (busySizing) return;
busySizing = true;
try {
tbcTests.ItemSize = new Size(
tbcTests.Width - tbcTests.TabPages[0].Controls[0].Width - tbcTests.Padding.X,
tbcTests.ItemSize.Height );
}
finally {
busySizing = false;
}
}

How do you resize a form to fit its content automatically?

I am trying to implement the following behaviour:
On a form there is a tabcontrol. On that tabcontrol there is a treeview. To prevent scrollbars appearing, I would like the form to change its size according to the contents of the treeview when displayed for the first time.
If the treeview has too many nodes to be displayed on the default size of the form, the form should change it's size so that there is no vertical scrollbar on the treeview (up to a maximum size allowed by the size of the screen).
What I need to know is, if it is possible to achieve this behaviour through the properties of the controls. I'm sure this can be achieved by calculating and settings the sizes of the elements programmatically, but I would like to know if there is a way to achieve this by settings like AutoSizeMode etc.
[UPDATE]
It's the first dialog a user of my application sees: It's a dialog to select the database to work with. It's a list of databases, with a tabcontrol, buttens etc. If the list is too long, scrollbars appear and a colleague of mine wants them to disappear.
Use the AutoSize and AutoSizeMode properties.
http://msdn.microsoft.com/en-us/library/system.windows.forms.form.autosize.aspx
An example:
private void Form1_Load(object sender, EventArgs e)
{
// no smaller than design time size
this.MinimumSize = new System.Drawing.Size(this.Width, this.Height);
// no larger than screen size
this.MaximumSize = new System.Drawing.Size(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, (int)System.Windows.SystemParameters.PrimaryScreenHeight);
this.AutoSize = true;
this.AutoSizeMode = AutoSizeMode.GrowAndShrink;
// rest of your code here...
}
By using the various sizing properties (Dock, Anchor) or container controls (Panel, TableLayoutPanel, FlowLayoutPanel, etc.) you can only dictate the size from the outer control down to the inner controls. But there is nothing (working) within the .Net framework that allows to dictate the size of a container through the size of the child control. I also missed this a few times and tried the AutoSize property, but it never worked.
So all you can do is trying to get this stuff done manually, sorry.
From MSDN:
To maximize productivity, the Windows Forms Designer shadows the
AutoSize property for the Form class. At design time, the form
behaves as though the AutoSize property is set to false,
regardless of its actual setting. At runtime, no special
accommodation is made, and the AutoSize property is applied as
specified by the property setting.
This might be useful.
It resizes a new form to a user control, and then anchors the user control to the new form:
Form f = new Form();
MyUserControl muc = new MyUserControl();
f.ClientSize = muc.Size;
f.Controls.Add(muc);
muc.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
f.ShowDialog();
You could calculate the required height of the TreeView, by figuring out the height of a node, multiplying it by the number of nodes, then setting the form's MinimumSize property accordingly.
// assuming the treeview is populated!
nodeHeight = treeview1.Nodes[0].Bounds.Height;
this.MaximumSize = new Size(someMaximumWidth, someMaximumHeight);
int requiredFormHeight = (treeView1.GetNodeCount(true) * nodeHeight);
this.MinimumSize = new Size(this.Width, requiredFormHeight);
NB. This assumes though that the treeview1 is the only control on the form. When setting the requiredFormHeight variable you'll need to allow for other controls and height requirements surrounding the treeview, such as the tabcontrol you mentioned.
(I would however agree with #jgauffin and assess the rationale behind the requirement to resize a form everytime it loads without the user's consent - maybe let the user position and size the form and remember that instead??)
This technique solved my problem:
In parent form:
frmEmployee frm = new frmEmployee();
frm.MdiParent = this;
frm.Dock = DockStyle.Fill;
frm.Show();
In the child form (Load event):
this.WindowState = FormWindowState.Maximized;
If you trying to fit the content according to the forms than the following will help. It helps me while I was trying to fit the content on the form to fit when ever the forms were resized.
this.contents.Size = new Size(this.ClientRectangle.Width,
this.ClientRectangle.Height);
I User this Code in my project, Useful for me.
private void Form1_Resize(object sender, EventArgs e)
{
int w = MainPanel.Width; // you can use form.width when you don't use panels
w = (w - 120)/4; // 120 because set 15px for each side of panels
// and put panels in FlowLayoutPanel
// 4 because i have 4 panel boxes
panel1.Width = w;
panel2.Width = w;
panel3.Width = w;
panel4.Width = w;
}
I used this code and it works just fine
const int margin = 5;
Rectangle rect = new Rectangle(
Screen.PrimaryScreen.WorkingArea.X + margin,
Screen.PrimaryScreen.WorkingArea.Y + margin,
Screen.PrimaryScreen.WorkingArea.Width - 2 * margin,
Screen.PrimaryScreen.WorkingArea.Height - 2 * (margin - 7));
this.Bounds = rect;

Categories

Resources