How do I get WebBrowsers url from the main Window C# WPF - c#

i have no idea how to get the Url from the WebBrowser that gets created with c# code and does not exist in the Xaml before the code is execeuted.. The AddTabItem() function is called at the start at the program and later on if user wants to add more TabItems user can click on the add button.
public List<TabItem> tabItem;
public MainWindow()
{
try {
InitializeComponent();
//nardimo array za TabItem
tabItem = new List<TabItem>();
//Dodamo zaznamek (tabItem)
TabItem novTab = this.AddTabItem();
//bajndam tab
tabControl.DataContext = tabItem;
tabControl.SelectedIndex = 0;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
public TabItem AddTabItem()
{
int count = tabItem.Count;
TabItem tab = new TabItem();
tab.Header = string.Format("Zavihek {0}", count+1);
tab.Name = string.Format("zavihek{0}", count);
WebBrowser wb = new WebBrowser();
wb.Name = string.Format("Brskalnik{0}", count);
string a = "http://www.google.com";
wb.Navigate(a);
Url.Text = a;
tab.Content = wb;
tabItem.Insert(count, tab);
return tab;
}
Then user can search on the Web and wanted to make a bookmark.. so how do I get the Url from the site when he clicks on the add bookmark button? How do I access the WebBrowser since it is not located in the Xaml code? Keep in mind I have to add bookmarks from the second window and not the main one. I am really sorry for my bad English and would be really happy if someone could help <3 Thank you guys

What you want is:
wb.Source.AbsoluteUri
If you drop a WebBrowser on your window and call it "wb", and a Button then you can do this in the code behind:
using System.Diagnostics;
using System.Windows;
namespace WpfApp1
{
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
wb.Navigate("http://google.com");
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Debug.WriteLine(wb.Source.AbsoluteUri);
}
}
}

You could use the references that you add to the List<TabItem>:
WebBrowser wb = tabItem[tabItem.Count - 1].Content as WebBrowser;
string url = wb.Source.AbsoluteUri.ToString();

Related

Accessing a control by specifying its container?

My WinForms program uses a WebBrowser control, and it creates a new TabPage with a WebBrowser control inside whenever the NewWindow event is triggered, using the following code:
private void WebBrowser1_NewWindow(object sender, System.ComponentModel.CancelEventArgs e)
{//open new window in new browser tab
string newUrl = browser.Document.ActiveElement.GetAttribute("href");
string pageName = "Page " + (tabControl1.TabCount + 1).ToString();
TabPage detailsTab = new TabPage(pageName);
Button closeTab = new Button();
closeTab.Anchor = (AnchorStyles.Top | AnchorStyles.Right);
closeTab.Location = new Point(10, 10);
closeTab.Text = "Close Tab";
closeTab.Click += new EventHandler(btnCloseTab_Click);
tabControl1.TabPages.Add(detailsTab);
WebBrowser detailsBrowser = new WebBrowser();
detailsBrowser.Dock = DockStyle.Fill;
detailsBrowser.Navigate(newUrl);
detailsTab.Controls.Add(detailsBrowser);
detailsTab.Controls.Add(closeTab);
closeTab.BringToFront();
tabControl1.SelectedIndex = tabControl1.TabCount -1;
}
So that each time a new browser tab is opened, a WebBrowser control called detailsBrowser is added to that tab. The problem is, if I need to get an HTML element from that browser, using something like:
HtmlElement saveButton = detailsBrowser.Document.GetElementsByTagName("input").GetElementsByName("save")[0];
I have no idea which detailsBrowser will be used to pull that HtmlElement.
I tried using
tabControl1.SelectedTab.Controls["detailsBrowser"]
instead of just referencing the browser by name, but this doesn't work and returns null when I try to get an HtmlElement from the browser.
Does anyone have a recommendation for how to specify a control using its container when multiple controls have the same name? Or is there a way to give each programmatically generated WebBrowser control a unique name?
Thanks!
EDIT: Here's the method I'm trying to use with the WebBrowser to select HTML elements:
public void addNote(string noteText)
{
WebBrowser currentBrowser = (WebBrowser) tabControl1.SelectedTab.Controls["detailsBrowser"];
HtmlElement showNotesButton = null;
//var links = browser.Document.GetElementsByTagName("div");
var links = currentBrowser.Document.GetElementsByTagName("div");
foreach (HtmlElement link in links)
{
if (link.GetAttribute("className") == "user_info_link")
{
showNotesButton = link;
}
}
//HtmlElement noteBox = browser.Document.GetElementById("remark");
HtmlElement noteBox = currentBrowser.Document.GetElementById("remark");
//HtmlElement submitNote = browser.Document.GetElementById("save_note");
HtmlElement submitNote = currentBrowser.Document.GetElementById("save_note");
showNotesButton.InvokeMember("click");
noteBox.Focus();
noteBox.InnerText = noteText;
Thread.Sleep(50);
submitNote.InvokeMember("click");
}

NET webbrowser - get HTML element ID by clicking on image

I have a C# winform project with a webbrowser control. I'm loading an HTML page with images into the webbrowser. Each image has a different ID:
<img src="F:\Temp\file12948.jpg" id="12948" width="180px">
Is there a way to pass the ID into a variable when clicking on the image so I can use the ID in my code? The path to the image can also be used as I can extract the number from there.
I have already searched here there and everywhere for a solution but can't find anything related.
You can dynamically attach to image's onClick event.
public class TestForm : Form
{
WebBrowser _WebBrowser = null;
public TestForm()
{
_WebBrowser = new WebBrowser();
_WebBrowser.ScriptErrorsSuppressed = true;
_WebBrowser.Dock = DockStyle.Fill;
this.Controls.Add(_WebBrowser);
WebBrowserDocumentCompletedEventHandler Completed = null;
Completed = (s, e) =>
{
//add onclick event dynamically
foreach (var img in _WebBrowser.Document.GetElementsByTagName("img").OfType<HtmlElement>())
{
img.AttachEventHandler("onclick", (_, __) => OnClick(img));
}
_WebBrowser.DocumentCompleted -= Completed;
};
_WebBrowser.DocumentCompleted += Completed;
var imgurl = "https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_120x44dp.png";
//_WebBrowser.Navigate("http://edition.cnn.com/2017/09/09/us/hurricane-irma-cuba-florida/index.html");
_WebBrowser.DocumentText = $"<html> <img src='{imgurl}' id=123 /> </html>";
}
void OnClick(HtmlElement img)
{
MessageBox.Show(img.GetAttribute("id"));
}
}
On simple way would be to use browser navigation. When clicking you can navigate to a special URL, then you handle the Navigating event and if the url is the special url you cancel the navigation and handle the data.
public MainWindow()
{
InitializeComponent();
br.NavigateToString(#"<img src=""F:\Temp\file12948.jpg"" id=""12948"" width=""180px"" >");
br.Navigating += this.Br_Navigating;
}
private void Br_Navigating(object sender, NavigatingCancelEventArgs e)
{
if(e.Uri.Host == "messages")
{
MessageBox.Show(e.Uri.Query);
e.Cancel = true;
}
}
This works if you have some control over the HTML. You could also set the URL from JS if you don't want to add the anchor.
Edit
The above version is for a WPF application. The winforms version is as follows:
public Form1()
{
InitializeComponent();
webBrowser1.DocumentText = #"<img src=""F:\Temp\file12948.jpg"" id=""12948"" width=""180px"" >";
webBrowser1.Navigating += this.webBrowser1_Navigating;
}
private void webBrowser1_Navigating(object sender, WebBrowserNavigatingEventArgs e)
{
if (e.Url.Host == "messages")
{
MessageBox.Show(e.Url.Query);
e.Cancel = true;
}
}

Display IE window using WebBrowser

I am working on a program that loads a webpage and calculates the load time. I want to give my program a URL and have it open an IE window at that page.
At first I was using Process.Start() to open the IE window, which works, but doesn't give me access to the WebBrowser.DocumentCompleted function. I am trying to create the IE window using a WebBrowser instance but I can't get the IE window to display.
using System;
using System.Windows.Forms;
namespace WebBrowserTest
{
public partial class Form1 : Form
{
WebBrowser IETestBrowser;
public Form1()
{
InitializeComponent();
IETestBrowser = new WebBrowser();
IETestBrowser.AllowNavigation = true;
IETestBrowser.Visible = true;
IETestBrowser.DocumentCompleted += ietb_DocumentCompleted;
}
private void LoadPageBtn_Click(object sender, EventArgs e)
{
IETestBrowser.Navigate("http://www.google.com");
IETestBrowser.Show();
TextDescriptionLbl.Text = "Loading Page...";
}
private void ietb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
TextDescriptionLbl.Text = "Done!";
}
}
}
This code works, and the DocumentCompleted event is triggered properly. I want the webpage to be visibly displayed in an IE window. How do I get the WebBrowser to draw on screen?
public Form1()
{
InitializeComponent();
IETestBrowser = new WebBrowser();
IETestBrowser.AllowNavigation = true;
IETestBrowser.Visible = true;
IETestBrowser.DocumentCompleted += ietb_DocumentCompleted;
//Add the WebBrowser Control to the form
IETestBrowser.Left = 100;
IETestBrowser.Top = 100;
this.Controls.Add(IETestBrowser);
}

Show a link to a path in a message form in c#

I have a desktop application in C# .In this I have a form in which I show different messages .
I have one message who say : "The output file was generated in : C:\Work\result.txt".
How can I show this path to the file as a link and when the form with this message is shown to see the path as a link and when the user click the link to open the specified path/file?
I tried :
The output file was generated in : C:\Work\result.txt
But doesn't work.
Thanks !
You can have an event for on-onclick, and then you can open file using the below code.
System.Diagnostics.Process.Start(#"C:\Work\result.txt"); //or like
System.Diagnostics.Process.Start(#"C:\Work\result.docx");
Here, the default program must be there for the file. Then only shell will run associated program reading it from the registry, like usual double click does in explorer.
MessageBox.Show() method takes the caption, text, icon, buttons and default button of the dialog.However there's nothing mentioned in the .NET Framework documentation that says anything about adding links to a MessageBox
However, you can do the effect you want by creating a new class inherited from System.Windows.Forms.Form and add a button (or more if you like), an icon, a label and a LinkButton. Then use the ShowDialog() Method of the Form class to display the message box in modal form. You may also create a class called MyErrorBox (static class in C# 2 or just sealed in C# 1) that contains only one static method called Show() which creates a form, adds the needed controls and displays the form in modal mode. A demonstration of the last method is shown below. Then you can use this class whenever you want and wherever you please!
using System;
using System.Windows.Forms;
using System.Drawing;
namespace MessageBoxes{
public sealed class MyErrorBox{
private MyErrorBox(){}
private static Form frm;
private static string detailsStore;
private static TextBox txt;
public static DialogResult Show(string caption, string text, string details, Icon icon){
frm = new Form(); frm.Size = new Size(510, 195);
frm.Text = caption; frm.ShowInTaskbar = false; frm.ControlBox = false;
frm.FormBorderStyle = FormBorderStyle.FixedDialog;
PictureBox icon1 = new PictureBox(); icon1.Location = new Point(8,16);
icon1.Size = new Size(icon.Width, icon.Height);
icon1.Image = icon.ToBitmap();
frm.Controls.Add(icon1);
Label lbl = new Label(); lbl.Text = text; lbl.Location = new Point(88,8);
lbl.Size = new Size(400,88); frm.Controls.Add(lbl);
LinkLabel btn1 = new LinkLabel(); btn1.Text = "View Details";
btn1.Size = new Size(72,23); btn1.Location = new Point(416,96);
btn1.Click += new EventHandler(btn1_Click); frm.Controls.Add(btn1);
//Ofcourse you can add more buttons than just the ok with more DialogResults
Button btn2 = new Button(); btn2.Text = "&Ok";
btn2.Size = new Size(72,23); btn2.Location = new Point(224,130);
btn2.Anchor = AnchorStyles.Bottom; frm.Controls.Add(btn2);
frm.AcceptButton = btn2; btn2.Click += new EventHandler(btn2_Click);
btn2.DialogResult = DialogResult.OK; detailsStore = details;
return frm.ShowDialog();
}
private static void btn1_Click(object sender, EventArgs e) {
frm.Size = new Size(510,320);
txt = new TextBox(); txt.Multiline = true;
txt.ScrollBars = ScrollBars.Both; txt.Text = detailsStore;
txt.Size = new Size(488,128); txt.Location = new Point(8,120);
txt.ReadOnly = true; frm.Controls.Add(txt);
LinkLabel lnk = (LinkLabel)(sender); lnk.Text = "Hide Details";
lnk.Click -= new EventHandler(btn1_Click);
lnk.Click += new EventHandler(btn1_ReClick);
}
private static void btn2_Click(object sender, EventArgs e) {
frm.Close();
}
private static void btn1_ReClick(object sender, EventArgs e) {
frm.Controls.Remove(txt); frm.Size = new Size(510, 195);
LinkLabel lnk = (LinkLabel)(sender); lnk.Text = "View Details";
lnk.Click -= new EventHandler(btn1_ReClick);
lnk.Click += new EventHandler(btn1_Click);
}
}
}
There's no standard MessageBox functionality that'll be able to do this via link label. What I suggest is you use the Yes/No Messagebox buttons and from the option selected you then apply an event
Something like this:
if (MessageBox.Show(
"The file is saved at the following link: link here", "Success", MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk
) == DialogResult.Yes)
{
System.Diagnostics.Process.Start(#"C:\TestLocation\SavedFiles");
}

How can I get a FlowDocument Hyperlink to launch browser and go to URL in a WPF app?

The following code in a WPF app creates a hyperlink that looks and acts like a hyperlink, but doesn't do anything when clicked.
What do I have to change so that when I click it, it opens the default browser and goes to the specified URL?
alt text http://www.deviantsart.com/upload/4fbnq2.png
XAML:
<Window x:Class="TestLink238492.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<StackPanel Margin="10">
<ContentControl x:Name="MainArea"/>
</StackPanel>
</Window>
Code Behind:
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
namespace TestLink238492
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
FlowDocumentScrollViewer fdsv = new FlowDocumentScrollViewer();
FlowDocument doc = new FlowDocument();
fdsv.Document = doc;
fdsv.VerticalScrollBarVisibility = ScrollBarVisibility.Hidden;
doc.PagePadding = new Thickness(0);
Paragraph paragraph = new Paragraph();
doc.Blocks.Add(paragraph);
Run run = new Run("this is flow document text and ");
paragraph.Inlines.Add(run);
Run run2 = new Run("this is a hyperlink");
Hyperlink hlink = new Hyperlink(run2);
hlink.NavigateUri = new Uri("http://www.google.com");
paragraph.Inlines.Add(hlink);
StackPanel sp = new StackPanel();
TextBlock tb = new TextBlock();
tb.Text = "this is textblock text";
sp.Children.Add(tb);
sp.Children.Add(fdsv);
MainArea.Content = sp;
}
}
}
I found the answer to this one, you have to add RequestNavigate and handle it yourself:
Run run2 = new Run("this is a hyperlink");
Hyperlink hlink = new Hyperlink(run2);
hlink.NavigateUri = new Uri("http://www.google.com");
hlink.RequestNavigate += new System.Windows.Navigation.RequestNavigateEventHandler(hlink_RequestNavigate);
paragraph.Inlines.Add(hlink);
void hlink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e)
{
Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri));
e.Handled = true;
}
Got the solutions for this Poma. The code section below should be added to your class where you need to do this. Or you can put it in a static class somewhere if you need to get to it from multiple files. I've tweaked it slightly for what I'm doing.
#region Activate Hyperlinks in the Rich Text box
//http://stackoverflow.com/questions/5465667/handle-all-hyperlinks-mouseenter-event-in-a-loaded-loose-flowdocument
void SubscribeToAllHyperlinks(FlowDocument flowDocument)
{
var hyperlinks = GetVisuals(flowDocument).OfType<Hyperlink>();
foreach (var link in hyperlinks)
link.RequestNavigate += new System.Windows.Navigation.RequestNavigateEventHandler(link_RequestNavigate);
}
public static IEnumerable<DependencyObject> GetVisuals(DependencyObject root)
{
foreach (var child in LogicalTreeHelper.GetChildren(root).OfType<DependencyObject>())
{
yield return child;
foreach (var descendants in GetVisuals(child))
yield return descendants;
}
}
void link_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e)
{
//http://stackoverflow.com/questions/2288999/how-can-i-get-a-flowdocument-hyperlink-to-launch-browser-and-go-to-url-in-a-wpf
Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri));
e.Handled = true;
}
#endregion Activate Hyperlinks in the Rich Text box
You'll call it in your code like this:
string xaml = HTMLConverter.HtmlToXamlConverter.ConvertHtmlToXaml(this.itemControl.NotificationItem.Body, true);
FlowDocument flowDocument = XamlReader.Load(new XmlTextReader(new StringReader(xaml))) as FlowDocument;
SubscribeToAllHyperlinks(flowDocument);
bodyFlowDocument.Document = flowDocument;
All the HTMLConverter stuff can be found at: http://blogs.msdn.com/b/wpfsdk/archive/2006/05/25/606317.aspx
That's if you need to convert HTML to a Flow Document. Although, that's slightly out of the scope of this topic.

Categories