2010-10-09 23 views
10

Làm cách nào để làm cho chế độ xem danh sách không tự động kiểm tra mục khi tôi nhấp đúp vào mục đó?ListView Winforms - Dừng tự động kiểm tra khi nhấp đúp vào

Tôi có thể thử móc vào sự kiện MouseDoubleClick và đặt thuộc tính Đã kiểm tra thành sai, nhưng điều đó giống như một chút hack. Tôi cũng chạy một phép tính hợp lý tốn kém khi một mục thực sự được kiểm tra và không muốn mã này chạy trên một nhấp đúp. Với sự kiện hooking ở trên, các sự kiện ItemCheck & ItemChecked được nâng lên trước khi nhấp đúp được xử lý.

Có giải pháp thanh lịch cho điều này không?

Trả lời

11

Thanh lịch thường không phải là từ nhảy vào tâm trí khi bạn phải hack cách điều khiển Windows bản địa hoạt động, nhưng đó là những gì được yêu cầu ở đây. Hãy xem xét nếu bạn thực sự muốn kiểm soát của bạn để hành xử khác nhau từ listviews trong bất kỳ chương trình khác.

Thêm lớp mới vào dự án của bạn và dán mã được hiển thị bên dưới. Biên dịch. Thả điều khiển mới từ đầu hộp công cụ lên biểu mẫu của bạn.

using System; 
using System.Windows.Forms; 

class MyListView : ListView { 
    protected override void WndProc(ref Message m) { 
     // Filter WM_LBUTTONDBLCLK 
     if (m.Msg != 0x203) base.WndProc(ref m); 
    } 
} 
+1

Hmmm, đây là cách ít hacky nhất để làm điều đó .... công việc này, đặc biệt nếu bạn gọi phương thức OnMouseDoubleClick từ WndProc khi tin nhắn được nhấn. Điều này bỏ qua việc xử lý Kiểm tra, trong khi vẫn giữ sự kiện nhấp đúp là những gì tôi muốn thực hiện. Cảm ơn! – Gareth

+0

Anh chàng này có sự thay thế tương tự, trong đó nhấp đúp cũng tiếp tục hoạt động: http://blogs.msdn.com/b/hippietim/archive/2006/03/27/562256.aspx –

11

Nếu bạn không muốn chuyển hoàn toàn các thư DoubleClick, nhưng chỉ tắt hành vi tự động. Thay vào đó, bạn có thể thực hiện các thao tác sau:

public class NoDoubleClickAutoCheckListview : ListView 
{ 
    private bool checkFromDoubleClick = false; 

    protected override void OnItemCheck(ItemCheckEventArgs ice) 
    { 
     if (this.checkFromDoubleClick) 
     { 
      ice.NewValue = ice.CurrentValue; 
      this.checkFromDoubleClick = false; 
     } 
     else 
      base.OnItemCheck(ice); 
    } 

    protected override void OnMouseDown(MouseEventArgs e) 
    { 
     // Is this a double-click? 
     if ((e.Button == MouseButtons.Left) && (e.Clicks > 1)) { 
      this.checkFromDoubleClick = true; 
     } 
     base.OnMouseDown(e); 
    } 

    protected override void OnKeyDown(KeyEventArgs e) 
    { 
     this.checkFromDoubleClick = false; 
     base.OnKeyDown(e); 
    } 
} 
+0

tuyệt vời, bao gồm chính xác nhu cầu của tôi và làm việc tốt cho tôi, cảm ơn! –

2

Tôi gặp sự cố tương tự và đây là cách tôi xử lý vấn đề này. Về cơ bản nếu mục được chọn trong khi tọa độ x của con trỏ lớn hơn tọa độ x của hộp kiểm, thì tôi hủy bỏ séc (vì nó có nghĩa là séc được gọi khi người dùng nhấp đúp vào mục đó).

Lề lỗi với số 22 chỉ khi người dùng nhấp đúp chuột ngay sau hộp kiểm (rất khó làm).

LƯU Ý: Mã của tôi giả định người dùng sẽ không tăng gấp đôi nhấp vào hộp kiểm (hoặc người sử dụng nhấp chuột gấp đôi so với mục hoặc nhấp chuột duy nhất hộp kiểm)

đang Xin lỗi là trong VB :)

Private Sub lvComboLists_ItemCheck(ByVal sender As Object, ByVal e As System.Windows.Forms.ItemCheckEventArgs) Handles lvComboLists.ItemCheck 
    Dim i As Integer = CType(sender, ListView).PointToClient(Cursor.Position).X 
    If i > 22 Then 
     e.NewValue = e.CurrentValue 
    End If 
End Sub 
+1

Bạn cần phải phân biệt giữa hành động của người dùng và hành động chương trình cho sự kiện ItemCheck. Tôi đã làm điều đó bằng cách thêm biến "boolean" MyDoing vào biểu mẫu để cho phép kiểm tra có nguồn gốc chương trình. –

+1

Tôi đã tìm thấy giải pháp khác này có vẻ đơn giản hơn (ít lộn xộn hơn): http://stackoverflow.com/questions/1406887/only-change-a-listviewitems-checked-state-if-the-checkbox-is-clicked –

1

Tôi sử dụng một phương pháp đơn giản hơn nhiều chỉ cần đặt lại giá trị của hộp kiểm về trạng thái ban đầu bằng cách thay đổi giá trị của nó thành đối diện với hiện tại:

Private Sub lst_Images_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles lst_Images.DoubleClick 
     Dim fIndex As Integer = Me.lst_Images.SelectedIndices(0) 
     ' Undo the changing of the checkbox's state by the double click event. 
     lst_Images.Items(fIndex).Checked = Not lst_Images.Items(fIndex).Checked 

     ' Call the viewer form 
     Dim fViewer As New Image_Edit(fIndex) 
     fViewer.ShowDialog() 
     fViewer.Dispose() 
End Sub 
Các vấn đề liên quan