Ja napisałem coś o co chyba chodzi w C# (dzisiaj już trzeci raz piszę coś dla kogoś, nie wiem co ze mną) ;)
Przykładowa aplikacja do przesuwania kolorowych prostokątów.
Wrzuciłem projekt (link)
Nowy plik, powinien zostać już na długo: Boxes.zip
Ale jak wiadomo pliki znikają a 4p pozostanie więc wrzucam główne źródła "ku pamięci"
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Box : UserControl
{
List<BoxItem> items;
bool moving;
BoxItem current; // <- pamiętaj że obiekty są przekazywane przez referencję
Point lastPos;
public Box()
{
InitializeComponent();
moving = false;
items = new List<BoxItem>();
}
public BoxItem this[int ndx]
{
get { return items[ndx]; }
set { items[ndx] = value; }
}
public void Add(BoxItem i)
{
this.items.Add(i);
Invalidate(i.Position); // Wymuszamy ponowne narysowanie fragmentu kontrolki gdzie
// boxItem się pojawia. Gdyby nie to, boxItem mógłby być
// niewidoczny.
}
protected override void OnPaint(PaintEventArgs e)
{
foreach (BoxItem i in items)
e.Graphics.FillRectangle(new SolidBrush(i.Color), i.Position);
base.OnPaint(e);
}
protected override void OnMouseMove(MouseEventArgs e)
{
if (!moving) return;
Point currPos = e.Location;
Point deltaPos = new Point(lastPos.X - currPos.X, lastPos.Y - currPos.Y);
current.Position = new Rectangle(
current.Position.X - deltaPos.X,
current.Position.Y - deltaPos.Y,
current.Position.Width,
current.Position.Height);
lastPos = currPos;
Invalidate(); // Można to __bardzo__ przyśpieszyć dając jedynie zmieniony prostokąt
// do narysowania.
base.OnMouseMove(e);
}
protected override void OnMouseDown(MouseEventArgs e)
{
foreach (BoxItem i in items)
{
if (i.Position.Contains(e.Location))
{
current = i;
moving = true;
lastPos = e.Location;
break;
}
}
base.OnMouseDown(e);
}
protected override void OnMouseUp(MouseEventArgs e)
{
moving = false;
base.OnMouseUp(e);
}
}
}
using System.Drawing;
namespace WindowsFormsApplication1
{
public class BoxItem
{
public BoxItem(Color color, Rectangle position)
{
this.Color = color;
this.Position = position;
}
public Color Color
{ get; set; }
public Rectangle Position
{ get; set; }
}
}
Update 8.2.2012 - jako że okazało się że dalej ktoś czasami wpada na ten kod, wysłałem małą poprawkę (związaną z dynamicznym dodawaniem obiektów do kontrolki - chodzi o Invalidate() w Add() ) i zrobiłem ponowny upload projektu.