So i was making a new script, and added basic drag functionality, but when i tested it with a placeholder image, nothing happened, it did not follow my mouse, and i don't know why.
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace mynamespace._2D
{
public sealed class WaterBucket : Control
{
public int Water { get; set; } = 100;
public int Capacity { get; set; } = 100;
public Image Sprite { get; set; }
public Window program;//The main form.
private bool IsDown = false;
public bool HitBox { get; set; } = false;
public Point ImageSize { get; set; }
//Constructor...
private void Program_MouseMove(object? sender, MouseEventArgs e)
{
if (!Enabled) return;
if (!IsDown) return;
Location = e.Location;
}
protected override void OnMouseUp( MouseEventArgs e)
{
if (!Enabled) return;
IsDown = false;
}
protected override void OnMouseDown(MouseEventArgs e)
{
if (!Enabled) return;
IsDown = true;
}
protected override void OnPaint(PaintEventArgs e)
{
if (!Visible) return;
Graphics g = e.Graphics;
g.DrawImage(Sprite,ClientRectangle);
if (!HitBox) return;
using Pen pen = new(Color.LightBlue, 5);
g.DrawRectangle(pen, new(new(ClientRectangle.Location.X + 5/2,ClientRectangle.Location.Y+5/2), new(ClientRectangle.Width - 5/2,ClientRectangle.Height-5/2)));
}
// Rest of code...
}
}
so i tried using a normal rectangle like Rectangle rect = new(Location,Size);
but it didn't do anything.
i also used to have these checks : if (IsDown) return; IsDown = true;
but removing those also didn't help.
for some reason CanSelect
and CanFocus
are readonly
so i can't know if they are actually true.
i Enabled = true;
this so i could know for sure it is enabled.
nothing worked though, and i tried adding debug statements but my output doesn't work.
also this is the placeholderimage in code:
public static Image PlaceHolder { get; } = Image.FromFile(Path.Combine(AppContext.BaseDirectory, "Images", "PlaceHolderImage.png"));
and this is the creation:
WaterBucket bucket = new(150,150,Program.PlaceHolder,program);
this is the image from the file if it helps:
The placeholder image
Thanks in advance!
The question is to which event is Program_MouseMove
attached?
I changed it to
protected override void OnMouseMove(MouseEventArgs e)
{
if (!Enabled) return;
if (!IsDown) return;
Location = Parent.PointToClient(PointToScreen(e.Location));
}
I also first translated the mouse coordinate which is local to the WaterBucket
to screen coordinates and then those back to the local coordinates of the parent of WaterBucket
(which may be the Form) because the Location
is set relative to the parent control or form.
This makes the top-left edge of WaterBucket
to be where the mouse moves to. This is not ideal. If you start by clicking somewhere inside the control, then this relative position should be maintained. You can achieve this by remembering the start location (relative to WaterBucket
) in a class field (_delta
). I also convert this Point
to a Size
that can later be subtracted from another location.
We need to consider the Enabled
property only in OnMouseDown
. There, we set IsDown
to true only if Enabled
is true.
// Only showing code relevant to moving this Control with the mouse.
public sealed class WaterBucket : Control
{
private bool IsDown = false;
private Size _delta;
protected override void OnMouseMove(MouseEventArgs e)
{
if (!IsDown) return;
Location = Parent.PointToClient(PointToScreen(e.Location)) - _delta;
}
protected override void OnMouseUp(MouseEventArgs e)
{
IsDown = false;
}
protected override void OnMouseDown(MouseEventArgs e)
{
IsDown = Enabled;
_delta = (Size)e.Location;
}
}