2010-03-22 4 views
5

Tôi sử dụng sự kiện MouseMove để di chuyển đối tượng (nói nhãn).Độ nhạy MouseMove

nguyên tắc đơn giản (sơ đồ):

OnMouseMove(e MouseEventArgs) 
    if e.Button == Left 
     deltaX = e.X - lastX 
     foreach label in labels 
      label.Location.X += deltaX 
     lastX = e.X 

Khi tăng nhãn số, tôi bắt đầu thấy các nhãn dấu vết dọc theo quỹ đạo chuyển động. Tôi có một cái gì đó như I I I II III II I I III II, nhưng muốn có một cái gì đó giống như tôi I I I như dấu vết. Tôi muốn biết khi nào chuột "bắt đầu" và "dừng lại để di chuyển" một cái gì đó như thế này.

Tôi di chuyển các nhãn dọc theo trục ngang. MouseDown (đặt LastX) và tiếp tục. Không ai biết khi nào dừng lại, chỉ có cảm giác di chuyển chuột. Chắc chắn tôi có thể sử dụng MouseUp để biết thời điểm chuyển động kết thúc, tuy nhiên nếu người dùng duy trì nút này và ngừng di chuyển, tôi muốn phản ánh vị trí nhãn mới nhất.

Có cách nào để ngăn chặn loại dấu vết này không?

thử

label.Visible = false 
label.Location.X += deltaX 
label.Visible = true 

không giúp.

parent.SuspendLayout and ResumeLayout không giúp được gì nhiều, bởi vì tôi cần thực hiện việc này ở mọi chuyển động của chuột, vì vậy có hiệu lực.

Trả lời

2

Chỉnh sửa: Tôi vừa mới nhận thấy chỉnh sửa của bạn về thời điểm chuột dừng lại. Bạn có thể sử dụng bộ hẹn giờ để giúp bạn. Có một thiết lập để khoảng thời gian bạn muốn cập nhật các vị trí trên và tự động thiết lập lại khi nó trôi qua. Bắt đầu nó trên chuột xuống và dừng nó trên chuột lên. Khi bộ đếm thời gian trôi qua, hãy cập nhật vị trí của nhãn.

-câu trả lời gốc cho bối cảnh: -

Vâng, bạn có thể đình chỉ vẽ trên sự kiểm soát của phụ huynh, di chuyển nhãn, và sau đó tiếp tục vẽ và làm mới.

Từ this SO question:

[DllImport("user32.dll")] 
public static extern int SendMessage(IntPtr hWnd, Int32 wMsg, bool wParam, Int32 lParam); 

private const int WM_SETREDRAW = 11; 

public static void SuspendDrawing(Control parent) 
{ 
    SendMessage(parent.Handle, WM_SETREDRAW, false, 0); 
} 

public static void ResumeDrawing(Control parent) 
{ 
    SendMessage(parent.Handle, WM_SETREDRAW, true, 0); 
    parent.Refresh(); 
} 

Ví dụ Cách sử dụng:

private void OnMouseMove(MouseEventArgs e) 
{ 
    int deltaX = e.X - lastX; 
    // Suspend drawing here 

    foreach (Label label in labels) 
    { 
     label.Location.X += deltaX; 
    } 

    lastX = e.X; 
    // Resume drawing here 
} 

Edit: Nếu bạn chỉ muốn hiển thị sự thay đổi ở vị trí nếu sự chênh lệch lớn hơn n pixel, sau đó bạn nên sử dụng Định lý Pythagore để tính toán khoảng cách giữa vị trí cũ và vị trí mới và chỉ di chuyển nó nếu chênh lệch lớn hơn n. Khi nút chuột xuất hiện, hãy di chuyển nhãn đến vị trí mà chúng được cho là theo chuột.

Pseudo-code:

difference = Math.Sqrt(x * x, y * y); 

if (difference > n) // n is whatever number you want 
{ 
    // move the labels 
    // set the old position to the new position 
} 
+0

hm. Vấn đề là tôi di chuyển nhãn rất thường xuyên. Tôi có một cái gì đó như tôi I II II III II I I III II, nhưng muốn có một cái gì đó như tôi Tôi Tôi Tôi Tôi Tôi như dấu vết. Tôi muốn biết khi nào chuột "bắt đầu" và "dừng lại để di chuyển" một cái gì đó như thế này. Tôi cũng có thể làm cho parent.Suspend/ResumeLayout() nhưng ... khi nào? – serhio

+0

@serhio: Tôi đã chỉnh sửa để bao gồm ví dụ về cách bạn có thể sử dụng SuspendDrawing/ResumeDrawing. Nếu tôi hiểu chính xác bạn, các nhãn không di chuyển "cùng nhau" (bạn thấy chúng di chuyển riêng). Giải pháp này sẽ giải quyết vấn đề đó. –

+0

@Zach. Vâng. nhưng...vấn đề là tôi muốn làm thay vì làm 10 chuyển động (nói từ 1 đến 20) chỉ 5. En gros, khi di chuyển "nhãn chứa" Tôi không cần phải nhìn thấy nhãn di chuyển, chỉ bắt đầu cuối cùng, và có thể một điểm trung gian là đủ. – serhio