Moving image on windows form - c#

Is it possible to make image, which is 'standing' still, move when I hover with my mouse over the image? I'm working in vs 2012, c# and win forms and I want simple movement like gif image, something similar to that, just to make it 'alive'
And how to make that? Thank you very much

It is - you can alter the Picturebox.Location like that. Note that this is an illustration and some edge cases may exist - for example you may want to add logic that detects when the image moved so much, that mouse went out (but within the original location)
private void pictureBox1_MouseEnter(object sender, EventArgs e)
{
int x = pictureBox1.Location.X;
int y = pictureBox1.Location.Y;
pictureBox1.Location = new Point(x + 25, y + 15);
}
private void pictureBox1_MouseLeave(object sender, EventArgs e)
{
int x = pictureBox1.Location.X;
int y = pictureBox1.Location.Y;
pictureBox1.Location = new Point(x - 25, y - 15);
}

Related

How to display only one clock pointer in c#

I'm trying to create an analog clock from scratch using C#, and I'm a little stuck at this point.
I have this code:
private void timer1_Tick(object sender, EventArgs e)
{
int seconde = DateTime.Now.Second;
spx = cx + (int)(length * Math.Sin(Math.PI * seconde / 30));
spy = cy - (int)(length * Math.Cos(Math.PI * seconde / 30));
a = new Point(spx, spy);
g.DrawLine(pen, m, a);
}
There are more variables in the form load but this is general how i draw the line for the second pointer on the clock. My problem is that it does exactly what i want. But after 60 seconds, I have 60 lines. How do I just display the good pointer line and/or delete the old lines.
Sorry if the answer to my problem is just easy. But I cant really find anything I understand as an answer.
You need to repaint the background of the clock every second before painting the new line, to remove the old line.
Of course, that would mean that for every paint of the seconds hand (or pointer) you will need to also paint the minutes hand and the hours hand, since both of them will also be deleted.
This is because winforms does not have the concept of painting in layers - everything gets painted on a single surface - so you have to first delete the old painting before you can paint a new one.
I would do it like this:
public partial class Form1 : Form
{
private int spx, spy, length;
private Pen pen = new Pen(new SolidBrush(Color.Red), 0.5f);
private Point a,m;
public Form1()
{
InitializeComponent();
}
private void timer1_Tick(object sender, EventArgs e)
{
this.Refresh(); // force redraw
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
length = Math.Min(e.ClipRectangle.Height, e.ClipRectangle.Width) / 2;
if (length != 0) // can't draw when there's no space
{
m = new Point(e.ClipRectangle.Width / 2, e.ClipRectangle.Height / 2);
int seconde = DateTime.Now.Second;
spx = m.X + (int)(length * Math.Sin(Math.PI * seconde / 30));
spy = m.Y - (int)(length * Math.Cos(Math.PI * seconde / 30));
a = new Point(spx, spy);
e.Graphics.DrawLine(pen, m, a);
}
}
}
I was taught to draw in OnPaint of Winforms controls.
Guess there are many different approaches.
By doing it this way you don't have to clear your graphics manually. This happens when the control is invalidated.

C# Linking point on form

Greeting!
I've been working on a project where you got a form where the user asks for a certain amount of dot (between 1 and 10). Then it draws them on a picturebox with a buttonclick action and then the user could click on any dot and a line between them is drawn.
So far it looks like this:
private void button1_Click(object sender, EventArgs e)
{
pictureBox1.CreateGraphics().Clear(this.BackColor);
Random r = new Random();
int db = new int();
Graphics rl = pictureBox1.CreateGraphics();
db = Convert.ToInt32(textBox1.Text);
if (db > 0 && db < 11)
{
for (int i = 0; i < db; i++)
{
rl.FillRectangle(new SolidBrush(Color.Black), r.Next(4, pictureBox1.Width - 4), r.Next(4, pictureBox1.Height - 4), 5, 5);
}
}
else
{
MessageBox.Show("Wrong number!");
}
}
This only draws the point on the form and i want to make them linkable. My idea is that i put it on a bitmap then i check the x,y coordinates and if the color is black (which means there is a point) I store in dot1 and dot2 and then simply make a drawline command like this:
private bool first = false;
private void Picturebox_Mouse(object sender, MouseEventArgs e)
{
Bitmap bm = new Bitmap(pictureBox1.Image);
Color color = bm.GetPixel(e.X, e.Y);
if (color == Color.Black & first==false)
{
dot1.X = e.X;
dot1.Y = e.Y;
first = true;
}
if (color == Color.Black & first == true)
{
dot2.X = e.X;
dot2.Y = e.X;
first = false;
}
rl.DrawLine(new Pen(Color.Black), dot1, dot2);
}
My question is that is my approach fine or i should do a different way? Also if this can work how do i put the content of the picturebox into a bitmap? I tried to drawing the point into the bitmap diractly then setting the pictureboxs image to the bitmap:
pictureBox1.DrawToBitmap(bm, new Rectangle(r.Next(0, pictureBox1.Width - 4), r.Next(0, pictureBox1.Height - 4), 5, 5));
pictureBox1.BackgroundImage = bm;
and also i tried to reverse it so putting the content to the bitmap:
Bitmap bm = new Bitmap(pictureBox1.Image);
but it doesn't seem to work. So can i get some ideas how to do it?
Any Kind of Idea is Appriciated!Thanks you.
I have done something similar, but as I was doing it on a web page I used an ImageButton instead of a PictureBox, so my code doesn't do exactly what you need, unfortunately. However, to use a bitmap with your image, you can do something like this:
Bitmap flag = new Bitmap(200, 100);
using(Graphics flagGraphics = Graphics.FromImage(flag))
{
// draw something on flagGraphics
pictureBox1.Image = flag;
}
(I actually based this on https://msdn.microsoft.com/en-us/library/ms404307(v=vs.110).aspx)
Note, you will need to change your test for black to something like if(color.ToArgb() == Color.Black.ToArgb()) or it won't work. Also you are setting a Y to an X value when I think it should be a Y!

Draw fractal Fit inside panel using Winform?

i am trying to build a windows application in .net which draw fractal image inside the panel.It take end points of line as starting point of next line.But problem is, diagram is going outside of the panel.How do i fix drawing inside the panel
static int start_x, start_Y;
static int end_x, end_Y;
static int my_angle = 0;
static int my_length = 0;
private void Canvas_Paint(object sender, PaintEventArgs e)
{
start_x = Canvas.Width / 2;
start_Y = Canvas.Height / 2;
for (int i = 0; i < 400; i++)
{
draw_T();
}
}
public void draw_T()
{
Pen mypen = new Pen(Color.Green, 2F);
my_angle = my_angle + (45);
my_length = 100 + (1);
end_x = (int)(start_x + Math.Cos(my_angle * .0174539676) * my_length);
end_Y = (int)(start_Y + Math.Sin(my_angle * .0174539676) * my_length);
Point[] points =
{
new Point (start_x,start_Y),
new Point (end_x,end_Y)
};
Point[] points1 =
{
new Point ((end_x+start_x)/2,(end_Y+start_Y)/2),
new Point (end_x+50,end_Y-100)
};
start_x = end_x;
start_Y = end_Y;
Graphics g = Canvas.CreateGraphics();
g.DrawLines(mypen, points);
g.DrawLines(mypen, points1);
}
I'm not sure how you graphic is supposed to look but I can give you a couple of hints.
At general one first: Do make use of e.Graphics parameter! Change
public void draw_T()
To
public void draw_T(Graphics g)
and delete the line.
Graphics g = Canvas.CreateGraphics();
Change the call to
draw_T(e.Graphics);
You are leaking GDI resource by creating all those Graphcs with disposing of them and and lose time by creating them when you already have the one from the Paint event.
Next you should add a NumericUpDown for testing your algorithm and script it like this:
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
Canvas.Invalidate();
}
To work you now change the loop to
for (int i = 0; i < numericUpDown1.Value; i++)
And watch your graphics develop.
Another test could be to introduce a second pen color for the second series of point.
To play around further you could add another NumericUpDown and tie my_lengthto it..
In the end you'll see that length needs to be smaller than 101 or the Canvas needs to be as large as 700 pixels.
BTW: Neither my_angle nor my_length need to be declared at class level since they are always set in the method and used nowhere else and no other variable needs to static either, at least from what you show us..

Selecting part of image on windows form

I'm making instrument to select part of image. I have PictrureBox, and simple way to make it :
void StartPanel(object sender, MouseEventArgs args)
{
xStart = args.X;
yStart = args.Y;
panelStarted = true;
pan.Location = new Point(xStart, yStart);
}
void FinishPanel(object sender, MouseEventArgs args)
{
xFinish = args.X;
yFinish = args.Y;
panelStarted = false;
}
void UpdatePanel(object sender, MouseEventArgs args)
{
if (panelStarted)
{
int x = args.X;
int y = args.Y;
int newxstart = xStart;
int newystart = yStart;
int neww = 0;
int newh = 0;
if (x >= xStart)
neww = x - xStart;
else
{
neww = xStart - x;
newxstart = x;
}
if (y >= yStart)
newh = y - yStart;
else
{
newh = yStart - y;
newystart = y;
}
pan.Size = new Size(neww, newh);
pan.Location = new Point(newxstart, newystart);
}
}
When I move mouse right and down, it is absolutely ok. But when I move it left or up I can see blinks at my area. So I have understood, that it is because when I move mouse left or up, my panel is redrawed, because Panel.Location is changed, and when I move mouse right and down, location is not changed, only size is changed, so it is not redrawed, just some pixels are added to panel. What is standart solution for this?
It's not easy trying to see what you are trying to do, but I guess you are using a panel as a draggable control to drag over the picturebox surface capturing the portion of image below (like a lens) - yes?
If so, then this is not the best way to do it. It is better to just draw a rectangle on the picturebox surface and "drag" that around - this is simple with just using the mouse events to sets the top left corner and use the onpaint to draw the unfilled rectangle over the image. Capturing the image when you are ready is simple too using whatever event you wish, then copy the image giving the same positions to the new bitmap.
Putting one control over another often causes flickers - even with double buffering. It also takes far more code.
Since you are describing a drawing issue when resizing the panel, probably the easiest fix is to replace the panel you are using with one that is double buffered and will invalidate on resize a event:
public class BufferedPanel : Panel {
public BufferedPanel() {
this.DoubleBuffered = true;
this.ResizeRedraw = true;
}
}

Turn a panel into a circle in C# Visual Studio 2010

I'm trying to make a basic soccer game in C#, and ive almost completed the field except for the various arcs and circles that are fairly important in the game, especially to set the bounds the computer's players cannot pass while their teammate/opponent is lining up for the kick.
So, all the methods I've tried havent worked because apparently I'm using fields like types, but I'm copying the code exactly. But I don't think its very important to show the buggy code, for a start I deleted it and I'd like the circles to be there permanently, not from when debugging starts.
So this is what I need: panels with round borders that stay round, and a way to put it in my code, which I'll post if necessary. Visual Studio C# Express 2010.
All help appreciated, thanks
One easy way to draw a circle on a panel is to inherit from Panel and override the OnPaint method. In this method you would call DrawEllipse on the Graphics object gotten from the event args. On point of interest is that the size is set to Width-1 and Height-1. This stops the right and bottom of the circle from dissapearing out of the Panel control.
One enhancement I have put in this code is to constrain the width & height in the OnResize method, this ensures your panel is always a circle, in oppose to an Ellipse (which can have different width and height). Simply drag this control onto a windows form and have a play in the designer.
public class CirclePanel : Panel
{
public CirclePanel()
{
}
protected override void OnPaint(PaintEventArgs e)
{
Graphics g = e.Graphics;
g.DrawEllipse(Pens.Black, 0,0,this.Width-1,this.Height-1);
}
protected override void OnResize(EventArgs e)
{
this.Width = this.Height;
base.OnResize(e);
}
}
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
Pen mypen;
Color mycolor=Color.Red;
Graphics mygraph;
int xloc = 50, yloc = 50;
public Form1()
{
InitializeComponent();
mygraph = CreateGraphics();
}
private void Form1_Load(object sender, EventArgs e)
{
}
float x = 270, y = 0.5f;
int xmover = 100, ymover = 48;
private void timer1_Tick(object sender, EventArgs e)
{
mygraph.DrawEllipse(new Pen(Color.Red), xloc, yloc, 102, 102);
mygraph.FillEllipse(new SolidBrush(Color.Red), xmover++, ymover++, 4, 4);
mycolor = this.BackColor;
mygraph.DrawPie(new Pen(mycolor), xloc+1, yloc+1, 100, 100, x-1, y);
mygraph.DrawPie(new Pen (Color.Red), xloc + 1, yloc + 1, 100, 100, x++, y);
mygraph.FillEllipse(new SolidBrush(mycolor), xmover-1, ymover - 1, 4, 4);
mygraph.DrawEllipse(new Pen(Color.Red), 100, 50, 5, 5);
}
}
}

Categories

Resources