Has any one successfully trapped the event of mouse scroll in a web browerser component?
I have two web browser controls i would like to scroll at the same time.
But there are no scroll events for web browsers.
I would like to create an event something like this below? has any one done or seen this before?
private void webCompareSQL_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
Document.Window.AttachEventHandler("OnScroll");
}
Here i would call my event and proceed with the code.
private void windowEvents_OnScroll()
{
int nPos = GetScrollPos(webCompareSQL.Handle, (int)ScrollBarType.SbVert);
nPos <<= 16;
uint wParam = (uint)ScrollBarCommands.SB_THUMBPOSITION | (uint)nPos;
SendMessage(WebPrevSQL.Handle, (int)Message.WM_VSCROLL, new IntPtr(wParam), new IntPtr(0));
}
I have found this code but don't know how to use it. its an event.
webCompareSQL.Document.Window.Scroll
I was able to get this working as follows. This example assumes that both web browser controls are navigating to the same Url. I am also syncing the horizontal scrollbar in addition to the vertical - this can be omitted if it is not required.
webBrowser1.DocumentCompleted
+= new WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted);
webBrowser2.DocumentCompleted
+= new WebBrowserDocumentCompletedEventHandler(webBrowser2_DocumentCompleted);
NavigateToPage("www.google.com");
....
private void NavigateToPage(string url)
{
webBrowser1.Navigate(url);
webBrowser2.Navigate(url);
}
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
webBrowser1.Document.Window.AttachEventHandler("onscroll", OnScrollEventHandler1);
}
private void webBrowser2_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
webBrowser2.Document.Window.AttachEventHandler("onscroll", OnScrollEventHandler2);
}
public void OnScrollEventHandler1(object sender, EventArgs e)
{
webBrowser2.Document.GetElementsByTagName("HTML")[0].ScrollTop
= webBrowser1.Document.GetElementsByTagName("HTML")[0].ScrollTop;
webBrowser2.Document.GetElementsByTagName("HTML")[0].ScrollLeft
= webBrowser1.Document.GetElementsByTagName("HTML")[0].ScrollLeft;
}
public void OnScrollEventHandler2(object sender, EventArgs e)
{
webBrowser1.Document.GetElementsByTagName("HTML")[0].ScrollTop
= webBrowser2.Document.GetElementsByTagName("HTML")[0].ScrollTop;
webBrowser1.Document.GetElementsByTagName("HTML")[0].ScrollLeft
= webBrowser2.Document.GetElementsByTagName("HTML")[0].ScrollLeft;
}
I note your comment in How to retrieve the scrollbar position of the webbrowser control in .NET, relating to this operation
webBrowser1.Document.GetElementsByTagName("HTML")[0].ScrollTop
not working. I can confirm that this definitely works on my machine, so if this code does not work on yours I can look into alternatives.
The real event name is "onscroll" not "OnScroll".
MSDN:http://msdn.microsoft.com/en-us/library/ie/ms536966(v=vs.85).aspx
Following code is firing the method when event occured.
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
webBrowser1.Document.Window.AttachEventHandler("onscroll", OnScrollEventHandler);
}
public void OnScrollEventHandler(object sender, EventArgs e)
{
}
Related
I recently started to learn C# and right now I want to mess arouwnd with the Form[Design].
Right now I'm trying to BringToFront() custom controls each time I hover over a button (Ive got a few buttons close to each other, each time I hover over them I get a certain User Control).
This is what I've got so far:
private void button1_Hover(object sender, EventArgs e)
{
costumControl1.BringToFront();
}
private void button1_Leave(object sender, EventArgs e)
{
CostumControl0.BringToFront();
}
private void button2_Hover(object sender, EventArgs e)
{
costumControl2.BringToFront();
}
private void button2_Leave(object sender, EventArgs e)
{
CostumControl0.BringToFront();
}
private void button3_Hover(object sender, EventArgs e)
{
costumControl3.BringToFront();
}
private void button3_Leave(object sender, EventArgs e)
{
CostumControl0.BringToFront();
}
But bringing to front the user control costumControl0 when I hover from a button to another it's not what I want.
But I don't know how to go about this.
Is it possible to just add a if statement where I check if I'm not hovering the buttons close to my current one and then display the costumControl0.
Or a timer is necessary to delay the display of the costumControl0 and skip the command if I'm starting another event.
If the timer is needed, can I use one timer for all of the buttons or do I need to create one for each?
Or whats the best approach for this?
I know from this question how to handle a drag&Drop
https://stackoverflow.com/a/17872857/982161
but I can not detect when the Drag event begins so I can prepare some resources...
if I print those events the Drop is coming first and after that the Drag..
how can this be cleanly handled
My Code is pretty simple
private void Label_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
var lbl = (Label)sender;
DragDrop.DoDragDrop(lbl, lbl.Content, DragDropEffects.Move);
Console.WriteLine("Drag...");
}
private void Label_Drop(object sender, DragEventArgs e)
{
Console.WriteLine("Drop...");
}
private void Label_DragEnter(object sender, DragEventArgs e)
{
Console.WriteLine("Label_DragEnter...");
}
private void Label_DragLeave(object sender, DragEventArgs e)
{
Console.WriteLine("Label_DragLeave...");
}
Long story short: If you want to prepare resources before you drop the label, write that code before calling the DragDrop method or in the OnPreviewMouseDown event.
Long Story:
Using Snoop I was able to look into the events that are triggering when dragging the label.
It appears that the only events triggering are the PreviewMouseDown and MouseDown.
So we should only implement those events.
private void Lbl_OnMouseDown(object sender, MouseButtonEventArgs e)
{
var lbl = (Label)sender;
DragDrop.DoDragDrop(lbl, lbl.Content, DragDropEffects.Move);
Console.WriteLine("Drag...");
}
private void UIElement_OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
{
Console.WriteLine("Label_PreviewMouseDown...");
}
This will result in first printing "Label_PreviewMouseDown..." when starting to drag the label and "Drag..." when the label is done being dragged.
However, this isn't the complete truth.
Let's modify our code a little. Let's add DateTime.Now.Second to test when the messages are actually triggering. I will then drag the label for a few seconds, then drop it to see the order of printing to console.
private void Lbl_OnMouseDown(object sender, MouseButtonEventArgs e)
{
var lbl = (Label)sender;
Console.WriteLine("Label_OnMouseDown_BeforeDragging..." + DateTime.Now.Second);
DragDrop.DoDragDrop(lbl, lbl.Content, DragDropEffects.Move);
Console.WriteLine("Label_OnMouseDown_AfterDragging..." + DateTime.Now.Second);
}
private void UIElement_OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
{
Console.WriteLine("Label_PreviewMouseDown..." + DateTime.Now.Second);
}
Now let's try dragging again.
Turns out that OnMouseDown happens before you are done dragging. The DoDragDrop method pauses the code there until you drop the label, then you are able to continue and print to the console.
So therefore: If you want to prepare resources before you drop the label, write that code before calling the DragDrop method or in the OnPreviewMouseDown event.
Hope this helps.
If you need a drag event that is not provided by the control then you may consider adding one to your own code. For example
// Event fired immediately before DragDrop
public DragEventHandler DragBegin { get; set; }
private void Label_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
var lbl = (Label)sender;
// Create args object and fire event if not null
var args = new DragEventArgs(new DataObject(lbl.Content), DragDropKeyStates.None, DragDropEffects.None, lbl, e.GetPoint(lbl));
DragBegin?.Invoke(sender, args);
DragDrop.DoDragDrop(lbl, lbl.Content, DragDropEffects.Move);
Console.WriteLine("Drag...");
}
You could then bind to that event from anywhere you have a reference to that code behind, such as
MyUserControl.DragBegin += (sender, args) => /* some behavior */;
I am looking to simulate a custom tooltip the like of you see in websites using c# .NET 4.5 windows forms.This tooltip will basically show status of some Tasks like how many tasks are pending,tasks in process, completed etc.To do this i am using a borderless win form.This winform will have some texts, images etc.I want it to reveal itself on button's mouseHover event and disappear on MouseLeave event.My problem is that on Mousehover event numerous instances of that tooltip form is getting generated and on MouseLeave they are not getting closed.My code is
private void B_MouseHover(object sender, EventArgs e)
{
frmSecQStatToolTipDlg tooltip = new frmSecQStatToolTipDlg();
tooltip.Location = this.PointToScreen(new Point(this.Left, this.Bottom));
tooltip.Show();
}
private void B_MouseLeave(object sender, EventArgs e)
{
frmSecQStatToolTipDlg tooltip = new frmSecQStatToolTipDlg();
tooltip.Close();
}
My code is not working, hence please tell me how to do this the correct way.Thanks
You're generating a new instance of the form class every time you get a hover event, and every time you get a leave event. If you want to continue to use this approach I would recommend you use a variable on your main form object to store the reference to your tooltip form. Secondly, you need to not generate a new instance whenever the event handler is called, but only when necessary. I would create your instance the first time your Hover event is called for a particular control, and then dispose of it when your Leave handler is called -- this is under the assumption that the tooltip dialog's constructor loads up different information for each control being hovered over. Like so:
frmSecQStatToolTipDlg f_tooltip;
private void B_MouseHover(object sender, EventArgs e)
{
if(frmSecQStatToolTipDlg == null)
{
f_tooltip = new frmSecQStatToolTipDlg();
}
tooltip.Location = this.PointToScreen(new Point(this.Left, this.Bottom));
tooltip.Show();
}
private void B_MouseLeave(object sender, EventArgs e)
{
if(f_tooltip != null)
{
f_tooltip.Close();
f_tooltip = null;
}
}
You should keep a global field for this form, and should not dispose or close it. Just hide it on some events and show again.
Sample Code:
frmSecQStatToolTipDlg tooltip;
private void B_MouseHover(object sender, EventArgs e)
{
if(frmSecQStatToolTipDlg == null)
{
tooltip = new frmSecQStatToolTipDlg();
}
tooltip.Location = this.PointToScreen(new Point(this.Left, this.Bottom));
tooltip.Show();
}
private void B_MouseLeave(object sender, EventArgs e)
{
if(frmSecQStatToolTipDlg != null)
{
tooltip.Hide();
}
}
With this logic you'll not have to create tooltip instance again and again and it will not take time to popup if you frequently do this activity.
Declare your tooltip once as readonly and use it without asking anytime if it is null or not.
If you need to Dispose it, implement the IDisposable pattern:
https://msdn.microsoft.com/en-us/library/b1yfkh5e(v=vs.110).aspx
private readonly frmSecQStatToolTipDlg _tooltip = new frmSecQStatToolTipDlg() ;
private void B_MouseHover(object sender, EventArgs e)
{
_tooltip.Location = this.PointToScreen(new Point(this.Left, this.Bottom));
_tooltip.Show();
}
private void B_MouseLeave(object sender, EventArgs e)
{
_tooltip.Hide();
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How To Start And Stop A Continuously Running Background Worker Using A Button
I have 2 buttons the first one it's name "Continuous" .. the second one "Stop"
I want to call a method when press the continuous button :
private void continuous_Click(object sender ,EvantArgs e)
{
// continuous taking pictures ...
}
my question is : how can I stop the execution by pressing the stop button ??
I've written a code to take a picture and I've succeeded to take pictures ...
now I want the camera to take continuous snapshots ... but if I press stop button the camera should stop taking pictures ...
I've used BackGroundWorker but the code does not work !!!
this is the code :
private void ContinousSnaps_Click(object sender, EventArgs e)
{
Contiguous.DoWork += Contiguous_DoWork;
Contiguous.RunWorkerCompleted += Contiguous_RunWorkerCompleted;
Contiguous.RunWorkerAsync();
}
private void Contiguous_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; ; i++) TakeSnapShotCommand();
}
private void Contiguous_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
MessageBox.Show("complete");
}
//------------------------------------------------------------------//
private void Stop_Click(object sender, EventArgs e)
{
Contiguous.CancelAsync();
}
//--------------------------------------------------------------------//
how can I achieve the result that I want ?!
Try and see if this is going to work:
In your _DoWork event:
private void Contiguous_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; ; i++)
{
if (Contiguous.CancellationPending)
{
e.Cancel = true;
return;
}
TakeSnapShotCommand();
}
}
And in the Stop_Click to the following:
private void Stop_Click(object sender, EventArgs e)
{
if (Contiguous.WorkerSupportsCancellation)
Contiguous.CancelAsync();
}
Also make sure you allow cancellation (and if you want to take my advice here - move these event registrations in a the form load, so they will be executed once, not every time the button is clicked - leave just the Continuous.RunWorkerAsync()):
// your form load <---
private void Form1_Load(object sender, EventArgs e)
{
Contiguous.DoWork += Contiguous_DoWork;
Contiguous.RunWorkerCompleted += Contiguous_RunWorkerCompleted;
Contiguous.WorkerSupportsCancellation = true; // allowing cancellation
}
private void ContinousSnaps_Click(object sender, EventArgs e)
{
// not a bad idea if you disable the button here at this point
Contiguous.RunWorkerAsync();
}
How to get the URI from webbrowser in listbox??
this code add a 20 URI not 1:
private void webBrowser1_DocumentCompleted(object sender,
WebBrowserDocumentCompletedEventArgs e)
{
radListControl1.Items.Add(webBrowser1.Url.AbsoluteUri.ToString());
}
or
private void webBrowser1_Navigated(object sender, WebBrowserNavigatedEventArgs e)
{
radListControl1.Items.Add(webBrowser1.Url.AbsoluteUri.ToString());
}
if (!radListControl1.Items.Contains(webBrowser1.Url.ToString()))
radListControl1.Items.Add(webBrowser1.Url.ToString());
Because this event is fired multiple times in single page load...
you need to check the URI provided by the event against the one in browser:
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
if (e.Url.Equals(webBrowser1.Url))
// this is the real one
}
EDIT: actually, it has already been answered.