Web browser control: How to capture document events?
Ok Answer found - tested and it works:
- Add a reference from the COM tab called: Microsoft HTML Object Library
The following is an example code:
You will need two components: WebBrowser (webBrowser1) and a TextBox (textBox1)
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
webBrowser1.LoadCompleted += new LoadCompletedEventHandler(webBrowser1_LoadCompleted);
}
private void webBrowser1_LoadCompleted(object sender, NavigationEventArgs e)
{
mshtml.HTMLDocument doc;
doc = (mshtml.HTMLDocument)webBrowser1.Document;
mshtml.HTMLDocumentEvents2_Event iEvent;
iEvent = (mshtml.HTMLDocumentEvents2_Event)doc;
iEvent.onclick += new mshtml.HTMLDocumentEvents2_onclickEventHandler(ClickEventHandler);
}
private bool ClickEventHandler(mshtml.IHTMLEventObj e)
{
textBox1.Text = "Item Clicked";
return true;
}
}
How to capture click event for any button inside in web browser control?
This will be helpful if you want to capture only mouse clicks:
WebBrowser _browser;
this._browser.DocumentCompleted+=new WebBrowserDocumentCompletedEventHandler(browser_DocumentCompleted);
...
private void browser_DocumentCompleted(Object sender, WebBrowserDocumentCompletedEventArgs e)
{
this._browser.Document.Body.MouseDown += new HtmlElementEventHandler(Body_MouseDown);
}
...
void Body_MouseDown(Object sender, HtmlElementEventArgs e)
{
switch(e.MouseButtonsPressed)
{
case MouseButtons.Left:
HtmlElement element = this._browser.Document.GetElementFromPoint(e.ClientMousePosition);
if(element != null && "submit".Equals(element.GetAttribute("type"),StringComparison.OrdinalIgnoreCase)
{
}
break;
}
}
can u please tell me how can i read custom attribute of any html
element loaded inside web browser control. thanks
If You don't want to link to "Microsoft.mshtml", You can try to use this sample method. But you can't read all members thru reflection:
public static String GetElementPropertyValue(HtmlElement element, String property)
{
if(element == null)
throw new ArgumentNullException("element");
if(String.IsNullOrEmpty(property))
throw new ArgumentNullException("property");
String result = element.GetAttribute(property);
if(String.IsNullOrEmpty(result))
{//В MSIE 9 получить свойство через DomElement не получается. Т.к. там он ComObject.
var objProperty = element.DomElement.GetType().GetProperty(property);
if(objProperty != null)
{
Object value = objProperty.GetValue(element.DomElement, null);
result = value == null ? String.Empty : value.ToString();
}
}
return result;
}
Capture click events inside a WPF WebBrowser control showing a PDF document
I ended up following a different approach. I decided to switch to a different UserControl, instead of the WPF WebBrowser, whenever a PDF content is recognized.
I knew that some classes and API for PDF rendering are available when you develop a Windows Store App, so I applied a solution in order to use those classes in my WPF application.
First I edited the csproj file adding the following tag as a child of <PropertyGroup>
:
<TargetPlatformVersion>8.1</TargetPlatformVersion>
then a section named "Windows 8.1" should appear in the Add Reference dialog window. I added the only assembly of this section to the references. Some more assemblies may be necessary in order to make the solution work:
- System.IO
- System.Runtime
- System.Runtime.InteropServices
- System.Runtime.InteropServices.WindowsRuntime
- System.Runtime.WindowsRuntime
- System.Threading
- System.Threading.Tasks
Once I had those, I wrote a render method that goes through the pages of the PDF file and creates a png file for each page. Then I added the pages to a StackPanel. At this point, you can manage the Click (or MouseDown) event on the StackPanel as you normally would on any UIElement.
Here is a brief example of the rendering methods:
async private void RenderPages(String pdfUrl)
{
try
{
HttpClient client = new HttpClient();
var responseStream = await client.GetInputStreamAsync(new Uri(pdfUrl));
InMemoryRandomAccessStream inMemoryStream = new InMemoryRandomAccessStream();
using (responseStream)
{
await responseStream.AsStreamForRead().CopyToAsync(inMemoryStream.AsStreamForWrite());
}
var pdf = await PdfDocument.LoadFromStreamAsync(inMemoryStream);
if (pdf != null && pdf.PageCount > 0)
{
AddPages(pdf);
}
}
catch (Exception e)
{
throw new CustomException("An exception has been thrown while rendering PDF document pages", e);
}
}
async public void AddPages(PdfDocument pdfDocument)
{
PagesStackPanel.Children.Clear();
if (pdfDocument == null || pdfDocument.PageCount == 0)
{
throw new ArgumentException("Invalid PdfDocument object");
}
var path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
StorageFolder rootFolder = await StorageFolder.GetFolderFromPathAsync(path);
var storageItemToDelete = await rootFolder.TryGetItemAsync(Constants.LOCAL_TEMP_PNG_FOLDER);
if (storageItemToDelete != null)
{
await storageItemToDelete.DeleteAsync();
}
StorageFolder tempFolder = await rootFolder.CreateFolderAsync(Constants.LOCAL_TEMP_PNG_FOLDER, CreationCollisionOption.OpenIfExists);
for (uint i = 0; i < pdfDocument.PageCount; i++)
{
logger.Info("Adding PDF page nr. " + i);
try
{
await AppendPage(pdfDocument.GetPage(i), tempFolder);
}
catch (Exception e)
{
logger.Error("Error while trying to append a page: ", e);
throw new CustomException("Error while trying to append a page: ", e);
}
}
}
Trigger event when WebBrowser text selection changed
You can attach an event handler to onselectionchange
event of Document
of the WebBrowser
control using AttachEventHandler
method of document. Then you can use properties of DomDocument
to get selected text.
Example
void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
webBrowser1.Document.AttachEventHandler("onselectionchange", selectionchange);
}
private void selectionchange(object sender, EventArgs e)
{
dynamic document = webBrowser1.Document.DomDocument;
dynamic selection = document.selection;
dynamic text = selection.createRange().text;
this.textBox1.Text= (string)text;
}
How to handle Javascript events via WebBrowser control for WinForms
Calling C# from JavaScript
Simply put, you can expose a C# object
to the WebBrowser that the JavaScript
can call directly The WebBrowser
class exposes a property called
ObjectForScripting that can be set by
your application and becomes the
window.external object within
JavaScript. The object must have the
ComVisibleAttribute set true
C#:
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
public class ScriptInterface
{
public void callMe()
{
… // Do something interesting
}
}
webBrowser1.ObjectForScripting = new ScriptInterface();
Javascript:
window.external.callMe();
Calling JavaScript in a WebBrowser control from C#
Related Topics
Difference Between Casting and Using the Convert.To() Method
C# Sha-1 VS. PHP Sha-1...Different Results
Can a Web User Control (.Ascx) Use a CSS File for Styling
Operators as Method Parameters in C#
How to Implement Url Rewriting Similar to So
Drawing Glitches When Using Creategraphics Rather Than Paint Event Handler for Custom Drawing
Converting Xdocument to Xmldocument and Vice Versa
Implicit VS Explicit Interface Implementation
How to Return Text from Native (C++) Code
Dynamically Setting CSS Values Using ASP.NET
Making a Private Method Public to Unit Test It...Good Idea
How to Avoid System.Io.Pathtoolongexception
Passing an Empty Array as Default Value of an Optional Parameter