I'm new in this forum, and my english is not perfect, so i want to excuse if my question isn't writen good.
I'm making a painting program with C# and all is perfect expect one problem.
When i'm drawing a line, or rectangle or elipse, when the mouseMove event is called the old shapes is drawed too.
How to draw a shape with mouseMove event and the old shapes to not been drawed.
Here is part of my code for more clarification.
//---Variables declared by the Prgrammer---//
//'parent' is variable that take the MdiParent
//'mouseIsDown' is boolean variable
//'startPoint' and 'endPoint' are Point Varables
//'pen' is Pen variable that is configured eralier
//'graphic' is pictureBox in the same form.
private void pbx_MouseDown(object sender, MouseEventArgs e)
{
if (parent.btnLine.Checked)
{
mouseIsDown = true;
startPoint = new Point(e.X, e.Y);
}
}
private void pbx_MouseMove(object sender, MouseEventArgs e)
{
if (mouseIsDown == true && parent.btnLine.Checked)
{
pen = new Pen(parent.btnPreview.BackColor, 12);
endPoint = new Point(e.X, e.Y);
graphic.DrawLine(pen, startPoint, endPoint);
}
}
private void pbx_MouseUp(object sender, MouseEventArgs e)
{
mouseIsDown = false;
}
Please help me. This is a big problem for me.
Thanks.
Please help me, i'm waiting 2 days.
When i'm making a new drawing to the graphic object, the old graphic is deleted.
I try the graphic.Save() method, but has not give me right result.
How to make the drawings to saty when i'm making another graphic?
As you're using picturebox you can use Invalidate() method.
Related
I would like to draw a rectangle around the selected item in a ListView, due to reading somewhere that Microsoft recommends against changing the 'highlighted colour' of said item. However, I'm using the selectedIndexChanged event and when the actual listviewitem is drawn my rectangle disappears. An educated guess would suggest my rectangle is either behind it or has being cleared when it has being redrawn? So my question is, when would be the best time to actually draw the rectangle as so it is visible? my code so far can be seen below:
void lvMain_SelectedIndexChanged(object sender, EventArgs e)
{
if (lvMain.SelectedItems.Count > 0)
{
if (lastSelectedItem == null) // First time called
{
lastSelectedItem = (sender as System.Windows.Forms.ListView).SelectedItems[0];
DrawHighlightRectanlge(lastSelectedItem);
}
else
{
// TODO: Remove previous highlight
lastSelectedItem = (sender as System.Windows.Forms.ListView).SelectedItems[0];
DrawHighlightRectanlge(lastSelectedItem);
}
}
}
internal void DrawHighlightRectanlge(System.Windows.Forms.ListViewItem item)
{
using (Graphics g = item.ListView.CreateGraphics())
{
g.DrawRectangle(new Pen(Color.Red), new Rectangle(item.Position.X, item.Position.Y, item.Bounds.Width, item.Bounds.Height));
}
}
TIA
Here is a very basic version for an owner-drawn ListView. Set the OwnerDraw property to true and code the DrawItem event, maybe like this:
private void listView1_DrawItem(object sender, DrawListViewItemEventArgs e)
{
e.DrawBackground();
e.DrawText();
if (e.Item.Selected)
{
Rectangle R = e.Bounds;
R.Inflate(-1, -1);
using (Pen pen = new Pen(Color.Red, 1.5f))
e.Graphics.DrawRectangle(pen, R);
}
}
I make the rectangle a little smaller for it to work in Details View, but you should play around to make it suit your needs and fancy..!
Note: If you have ColumnHeaders you also need to code the DrawColumnHeader event, in its simplest form like this:
private void listView1_DrawColumnHeader(object sender,
DrawListViewColumnHeaderEventArgs e)
{
e.DrawDefault = true;
}
And if you have SubItems you need to have a DrawSubItem event, again at least like this:
private void listView1_DrawSubItem(object sender, DrawListViewSubItemEventArgs e)
{
e.DrawDefault = true;
}
Obviously you need to write more code to this event, if you want your rectangle to be drawn here as well. But the default function of DrawBackground and DrawText are available here as well.
In a System.Windows.Forms.Panel (in C# and .NET 4.5.1) I have to follow the cursor position with two crossing perpendicular lines.
Using ControlPaint.DrawReversibleLine somtimes parts or whole old lines persist.
This happen in a random manner and applying or not the style:
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true)
as suggested in MSDN.
Temporarily solved using a cross cursor but I have to do it.
If anyone can give me hint...
Thank you
D.R.
Forget DrawReversibleLine!
This will do what you told us you want to do:
Point mouse = Point.Empty;
private void panel1_MouseMove(object sender, MouseEventArgs e)
{
mouse = e.Location;
panel1.Invalidate();
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
if (mouse != Point.Empty)
{
e.Graphics.DrawLine(Pens.Blue, 0, mouse.Y, panel1.ClientSize.Width, mouse.Y );
e.Graphics.DrawLine(Pens.Blue, mouse.X, 0, mouse.X, panel1.ClientSize.Height );
}
}
private void panel1_MouseLeave(object sender, EventArgs e)
{
mouse = Point.Empty;
panel1.Invalidate();
}
But it will not do what you didn't tell us.
Note: You will need to update anthing else on drawn that Panel - I hope there is nothing, otherwise it needs to be redrawn from the Paint event..
I have a question regarding how I can prevent some content drawn on a panel control from being erased when a scroll action brings it out of view.
What I am trying to do is create a 2D tile-map editor. Whenever a mouse click event happens on the panel, a tile should get drawn onto the panel. I have this working fine. But if I place the object on the panel and scroll to one side, and scroll back, the object I had placed is gone.
I have done some research and I have seen suggestions on implementing the paint event. The problem is that I do not understand what to implement here. I think most of my struggles is coming from not fully understanding the Graphics object.
Here is some of my code:
private void canvas_MouseClick(object sender, MouseEventArgs e)
{
Graphics g = canvas.CreateGraphics();
float x1 = CommonUtils.GetClosestXTile(e.X);
float y1 = CommonUtils.GetClosestYTile(e.Y);
if (currentTile != null)
{
g.DrawImage(currentTile, x1, y1);
me.AddTile((int)currX, (int)currY, (int)x1, (int)y1, "C:\\DemoAssets\\tileb.png");
}
else
{
// dont do anything
}
g.Dispose();
}
private void canvas_Paint(object sender, PaintEventArgs e)
{
// update here?
}
To hold multiple Tiles, you'd need a List to hold each clicked location along with its associated tile:
List<Tuple<Image, PointF>> Tiles = new List<Tuple<Image, PointF>>();
private void canvas_MouseClick(object sender, MouseEventArgs e)
{
if (currentTile != null)
{
float x1 = CommonUtils.GetClosestXTile(e.X);
float y1 = CommonUtils.GetClosestYTile(e.Y);
Tiles.Add(new Tuple<Image, PointF>(currentTile, new PointF(x1, y1)));
canvas.Refresh();
me.AddTile((int)currX, (int)currY, (int)x1, (int)y1, "C:\\DemoAssets\\tileb.png");
}
}
private void canvas_Paint(object sender, PaintEventArgs e)
{
foreach (Tuple<Image, PointF> tile in Tiles)
{
e.Graphics.DrawImage(tile.Item1, tile.Item2);
}
}
I have panel1 in my form, i set the visible property to panel1.Visible=false; I want to show this panel wherever i click on the screen.
I need to grab the current mouse location and then display the panel1 where the top-left corner must be in the same point as the mouse cursor !
Sorry for being so beginner but i really stuck on how to do it.
Code that i tried :
private void dataGridView1_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
{
panel1.Location = e.Location;
panel1.Show();
}
It might this will be your guide to your task, just use the .PointToScreen and .GetCellDisplayRectangle Method
private void dataGridView1_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
{
if (e.ColumnIndex == -1) return;
var cellRectangle = dataGridView1.PointToScreen(
dataGridView1.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false).Location);
panel1.Location = new Point(cellRectangle.X + 50, cellRectangle.Y - 175);
panel1.Show();
}
As far I can recognize your problem you should use PointToScreen function - more on this here
I want to get the position of the picturebox that has been cliked by the mouse,but i don't know how??
I mean the position of picturebox not the form that the picturebox on it.
thanks.
MUGAN's close. The Point you'll get from MouseEventArgs is the "screen" point of the mouse, where 0,0 is the top left of the entire monitor or desktop (however you want to think of it). To convert that to a "client" point within the PictureBox control, where 0,0 is the top left of that PictureBox, you'll need to use the Control.PointToClient() method:
private void pb_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
Point mouseDownLocation = (Control)sender.PointToClient(new Point(e.X, e.Y));
//here goes your if condition ...
}
private void pb_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
Point mouseDownLocation = new Point(e.X, e.Y);
//here goes your if condition ...
}