I want to click a button which is at certain location (X,Y coordinate) inside a webbrowser control in windows form. But I am unable to find the correct location. The current coding shifts point somewhere else then the exact point.
private void Document_MouseUp(object sender, HtmlElementEventArgs e)
{
Point cp = this.PointToClient(Cursor.Position); // Getting a cursor's position according form's area
MessageBox.Show("Cursor position: X = " + cp.X + ", Y = " + cp.Y);
}
webBrowser1.Document.MouseUp += new HtmlElementEventHandler(Document_MouseUp);
Point ScreenCoord = new Point(815, 192); //This value is returned by Document_MouseUp
//Point BrowserCoord = webBrowser1.PointToClient(ScreenCoord);
HtmlElement elem = webBrowser1.Document.GetElementFromPoint(ScreenCoord);
if (elem.InnerText.Equals("Something"))
{
elem.InvokeMember("Click");
}
Related
Windows Forms ZedGraph control in WPF application. The data points are auto-generated and attached to the chart every N seconds. When new data point is added to the chart I shift (pan) chart one point to the left, so there is always no more than last 50 points visible in the viewport. Overall, it works pretty good, except for two things.
Issues
If user tries to zoom in or out, the viewport stops following the last data point and chart goes outside of the screen, so panning stops working
I would like to pan or shift chart using mouse event, without scrolling, but when I press right mouse button and try to move it to the left, it tries to zoom chart instead of panning
protected void CreateChart(ZedGraphControl control)
{
_rand = new Random();
var curve = control.GraphPane.AddJapaneseCandleStick("Demo", new StockPointList());
curve.Stick.IsAutoSize = true;
curve.Stick.Color = Color.Blue;
control.AutoScroll = true; // Always shift to the last data point when new data comes in
control.IsEnableHPan = true; // I assume this should allow me to move chart to the left using mouse
control.IsEnableVPan = true;
control.IsEnableHZoom = true;
control.IsEnableVZoom = true;
control.IsShowPointValues = true;
control.IsShowHScrollBar = false;
control.IsShowVScrollBar = false;
control.IsAutoScrollRange = true; // Always shift to the last data point when new data comes in
control.IsZoomOnMouseCenter = false;
control.GraphPane.XAxis.Type = AxisType.DateAsOrdinal;
control.AxisChange();
control.Invalidate();
var aTimer = new Timer();
aTimer.Elapsed += new ElapsedEventHandler(OnTime);
aTimer.Interval = 100;
aTimer.Enabled = true;
}
protected XDate _xDate = new XDate(2006, 2, 1);
protected double _open = 50.0;
protected Random _rand = new Random();
// Auto generate data points
protected void OnTime(object source, ElapsedEventArgs e)
{
var control = FormCharts;
var x = _xDate.XLDate;
var close = _open + _rand.NextDouble() * 10.0 - 5.0;
var hi = Math.Max(_open, close) + _rand.NextDouble() * 5.0;
var low = Math.Min(_open, close) - _rand.NextDouble() * 5.0;
var pt = new StockPt(x, hi, low, _open, close, 100000);
_open = close;
_xDate.AddDays(1.0);
if (XDate.XLDateToDayOfWeek(_xDate.XLDate) == 6)
{
_xDate.AddDays(2.0);
}
(control.GraphPane.CurveList[0].Points as StockPointList).Add(pt);
control.GraphPane.XAxis.Scale.Min = control.GraphPane.XAxis.Scale.Max - 50; // Hide all points except last 50, after mouse zooming this line stops working
//control.GraphPane.XAxis.Scale.Max = control.GraphPane.XAxis.Scale.Max + 1;
control.AxisChange();
control.Invalidate();
}
Kind of solved it.
First issue with broken auto-scroll after zooming
It happens because zooming sets these parameters to FALSE.
area.XAxis.Scale.MinAuto = false;
area.XAxis.Scale.MaxAuto = false;
To fix it, either set it back to TRUE every time new data point comes. Another way to fix it, is to keep them always as FALSE and move chart manually
protected void MoveChart(GraphPane pane, int pointsToMove, int pointsToShow)
{
pane.XAxis.Scale.Max = pane.XAxis.Scale.Max - pointsToMove;
pane.XAxis.Scale.Min = pane.XAxis.Scale.Max - Math.Abs(pointsToShow);
}
...
// Example : shift one point to the left and show only 50 last points
MoveChart(control.MasterPane.PaneList["Quotes"], -1, 50);
Second issue, implementing custom panning without scrollbar using mouse events.
protected int _mouseX = -1;
protected int _mouseY = -1;
...
control.MouseUpEvent += OnMouseUp;
control.MouseDownEvent += OnMouseDown;
control.MouseMoveEvent += OnMouseMove;
...
// Example : remember X and Y on mouse down and move chart until mouse up event
protected bool OnMouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
_mouseX = -1; // unset X on mouse up
_mouseY = -1;
return true;
}
protected bool OnMouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
_mouseX = e.X; // remember last X on mouse down
_mouseY = e.Y;
return true;
}
protected bool OnMouseMove(ZedGraphControl sender, System.Windows.Forms.MouseEventArgs e)
{
if (_mouseX >= 0) // if X was saved after mouse down
{
foreach (var pane in sender.MasterPane.PaneList) // move synced chart panels
{
MoveChart(pane, _mouseX > e.X ? -1 : 1, 50); // if mouse move is increasing X, move chart to the right, and vice versa
}
_mouseX = e.X; // update X to new position
_mouseY = e.Y;
}
return true;
}
What's the deal, i have an imagePanel (u can look at it as a picturePanel)
called imagePanel1 (i imported it so i don't have to make scroll Bars :))
and i have a treeView on the left side, from witch i can drag a node, and drop it over the imagePanel, where i get a Location of the drop, and on that location i create a normal panel called panel1
And so i do 100 times, so at the end i ll have an imagePanel full of small panels...
Now is the problem, when i click on the imagePanel (where a panel is located)
I want that panel to be selected on MousePress, and moved on mouseMove, and eventualLy deleted on a btnDelete...
Here is the code for the imagePanel:
//***********************************************************************
private void imagePanel1_DragDrop_1(object sender, DragEventArgs e)
{
Type testTip = new TreeNode().GetType();
YLScsImage.ImagePanel dropPicturePanel = (YLScsImage.ImagePanel)sender;
TreeNode movedNode;
_mouseDownSelectedWindow = Rectangle.Empty;
if (e.Data.GetDataPresent(testtype))
{
movedNode= (TreeNode)e.Data.GetData(testType);
dropPicturePanel.Tag = movedNode.Tag;
movedNode.ImageIndex = 1;
movedNode.SelectedImageIndex = 1;
movedNode.ForeColor = Color.Gray;
//**************************************
//HERE IS THE CODE FOR THE CREATED PANEL
Panel panel1 = new Panel();
Point point1 = this.PointToClient(new Point(e.X - 278, e.Y - 19)); //the imagePanel1 is on the form at the point 278,19
panel1.AllowDrop = true;
panel1.Location = point1;
panel1.BackgroundImage = iltest.Images[0]; //nvm
panel1.Height = 16;
panel1.Width = 16;
imagePanel1.Controls.Add(panel1); //am adding it to the imagePanel1
//saving the locations of each panel
string path = #"C:\Users\Cosic\Desktop\ICR\TABELA3_Paneli.txt"; // path to file
if (!File.Exists(path))
File.Create(path);
if (panelBr == 0)
System.IO.File.WriteAllBytes(path, new byte[0]); //brise ceo text iz fajla
TextWriter sw = new StreamWriter(path, true);
sw.WriteLine(e.X + "; " + e.Y + "; " + panel1.Width + "; " + panel1.Height + ";");
sw.Close();
//am done with saving
panelBr++;//nvm
}
}
tell me if u need some more code...i got a lot of it ;)
and sorry for bad english, am not that good as I would like to be...
I solved the problem, like this:
panel1.MouseUp += new MouseEventHandler(panel1_MouseUp);
just write panel1.anyEventUWant += and 2 times tab button....
it generate automaticly a new function with a single code line in it
here is an example
void panel1_MouseUp (object sender, EventArgs e)
{
//throw new NotImplementedException();
}
U can access the panel like this: ((object)sender).
In the details view of ListView control, I need additional functionality of editing the entry pointed to by the cursor so I simply added a button overlay onto the ListView control.
The following code was intended to show the button on the rightmost part of each cell of the details view of ListView control when the cursor is on the ListView control.
To determine which cell was hovered, HitTest method was used.
The problem is, the button show correctly only when the cursor is on the rectangle area the button is supposed to show up. In other words, when the cursor is on non-rightmost area of any field, redraw occurs in ListView control and erases the button (and the content of the cell). Also, BringToFront method doesn't work.
How to correct this behavior?
class DocumentView {
Button btn = new Button();
ListView lv; // designer-generated
public DocumentView(Document doc)
{
btn.AutoSize = true;
btn.AutoSizeMode = AutoSizeMode.GrowAndShrink;
btn.AutoEllipsis = false;
btn.Hide();
this.Controls.Add(btn);
InitializeComponent();
}
ListViewItem mouseMoveHitTestItem = null;
ListViewItem.ListViewSubItem mouseMoveHitTestSubItem = null;
int iCol_MouseMove = -1;
int iRow_MouseMove = -1;
private void lv_MouseMove(object sender, MouseEventArgs e)
{
var mousePos = lv.PointToClient(Control.MousePosition);
var hitTest = lv.HitTest(mousePos);
mouseMoveHitTestItem = hitTest.Item;
mouseMoveHitTestSubItem = hitTest.SubItem;
if (mouseMoveHitTestItem != null)
{
var iCol = hitTest.Item.SubItems.IndexOf(hitTest.SubItem);
var iRow = hitTest.Item.Index;
if (iCol != iCol_MouseMove || iRow != iRow_MouseMove)
{ //Reposition button if the cursor moved to a different cell
var bounds = hitTest.SubItem.Bounds;
btn.SetBounds(
bounds.Right - btn.Width + lv.Left,
bounds.Top + lv.Top,
bounds.Width, bounds.Height);
if (!btn.Visible)
{
btn.Show();
btn.BringToFront();
}
btn.Text = "" + iRow + ", " + iCol; //test hittest row, col calc.
}
}
btn.BringToFront(); //takes no effect
}
}
Missed status update so invalidatation occurred on every MouseMove:
btnAddName.SetBounds(
bounds.Right - btnAddName.Width + lvVertices.Left,
bounds.Top + lvVertices.Top,
bounds.Width, bounds.Height);
//-->
iColBtnAdd = iCol;
iRowBtnAdd = iRow;
//<--
if (!btnAddName.Visible)
{
Warnings help. (CS0169)
Can someone help me solve the question: How can I divide the figure into the fields, so depending on which area will be mouse click it will be carried out a specific event?
private void LayoutRoot_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
//if (!isDragging)
{
//creating of my user control element
NodePicture node = new NodePicture();
node.Width = 100;
node.Height = 100;
//use cursor position as the center of the figure
Point point = e.GetPosition(this);
node.SetValue(Canvas.TopProperty, point.Y - node.Height / 2);
node.SetValue(Canvas.LeftProperty, point.X - node.Width / 2);
node.MouseLeftButtonDown += controlReletionshipsLine;
LayoutRoot.Children.Add(node);
}
}
private void controlReletionshipsLine(object sender, MouseButtonEventArgs e)
{
//creating parant element of node
ParentNode parentNode = new ParentNode();
//creating connected element of the node
ConnectedNode connectedNode = new ConnectedNode();
//creating node element
NodePicture node = (NodePicture)sender;
//getting the relative position of the element
Point point = e.GetPosition(this);
You can either divide the object mathematically, using the mouse position "relative to the object" to decide where you clicked, or you can overlay a number of polygons, each with the colour alpha-channel set to 1% (so they can be hit-tested, but are not visible).
As you simply want to see which quarter of the circle you clicked in, call GetPosition on the LeftMouseButtonDown event args, passing the control itself as the parameter. This will give you back a Point object with the position relative to the top left corner of the control.
Then it is just a matter of seeing which quarter it is in:
private void ControlX_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
// Get the relative position of the element
Point point = e.GetPosition(sender as UIElement);
if (point.X > control.Width/2)
{
if (point.Y > control.Height/2)
{
// You are in the bottom right quarter
}
else
{
// You are in the top right quarter
}
}
else
{
if (point.Y > control.Height/2)
{
// You are in the bottom left quarter
}
else
{
// You are in the top left quarter
}
}
}
In the sample code you sent me (in controlReletionshipsLine) you have:
// getting the relative position of the element
Point point = e.GetPosition(this);
It should have been:
// getting the relative position of the element
Point point = e.GetPosition(sender as UIElement);
void dataGridView1_DragDrop(object sender, DragEventArgs e)
{
object data = e.Data.GetData(typeof(string));
MessageBox.Show(e.X + " " + e.Y + " " + dataGridView1.HitTest(e.X, e.Y).RowIndex.ToString());
if (dataGridView1.HitTest(e.X, e.Y).Type == DataGridViewHitTestType.Cell)
{
MessageBox.Show("!");
}
}
If I try to drag an item to a datagridview with the above test code, I receive the correct data from the data.ToString() ok but i cannot target a row or cell.
The RowIndex.ToString() returns "-1", and my if statement returns false so never enters if coded block.
What is wrong with my code?
I believe the coordinates being passed from DragAndDrop are screen space coordinates.
I think you need to cast the points to the client coordinates space.
Point dscreen = new Point(e.X, e.Y);
Point dclient = dataGridView1.PointToClient(dscreen );
DataGridView.HitTestInfo hitTest = dataGridView1.HitTest(dclient.X,dclient.Y);
then hitTest.Row will have the row index