2010-11-03 21 views
24

Các WinForms CheckedListBox điều khiển có 2 hành vi mặc định khi nhấn với một con chuột:hành vi Odd khi nhà nước kiểm tra Toggling CheckedListBox mục của qua mouseclick khi nhấp vào lựa chọn cùng

  1. Để kiểm tra/bỏ chọn một mục bạn bắt buộc phải nhấp vào một mục hai lần. Nhấp chuột đầu tiên chọn mục và thứ hai chuyển sang trạng thái kiểm tra.
  2. Ngoài ra, một nhấp chuột tiếp theo của cùng một mục sẽ chuyển trạng thái đã chọn của mục đó.

Là tính năng tiện lợi, tôi cần cho phép người dùng chuyển đổi lựa chọn trong một lần nhấp. Tôi đã đạt được điều này, vì vậy bây giờ hành vi mặc định # 1 ở trên là đạt được trong một cú nhấp chuột. Vấn đề là hành vi # 2 không còn hoạt động chính xác khi nhấp vào cùng một mục (tức là, hiện được chọn). Nó hoạt động tốt khi nhảy giữa các mục, đó là mong muốn, nhưng nó đòi hỏi lên đến 4 lần nhấp chuột vào cùng một mục.

Giải pháp cho việc này là gọi logic chuyển đổi hai lần nếu người dùng chọn cùng một mục nhiều lần. Vì vậy, đối với câu hỏi của tôi:

  1. Điều này có hiệu quả, nhưng tại sao? Vấn đề cơ bản thực sự là gì?
  2. Có cách nào tốt hơn để đạt được điều này để tôi có thể làm cho nó hoạt động như hành vi mặc định # 2 mà không gọi phương thức hai lần và theo dõi lựa chọn cuối cùng của tôi không?

Rất khó sửa mã cho thấy trạng thái đã chọn đã thay đổi nhưng không xuất hiện ở phía giao diện người dùng cho đến khi được gọi hai lần. Tôi nghĩ rằng nó có thể được luồng liên quan nhưng nó không phải là một sự kiện lại entrant được kích hoạt mà có thể cần sử dụng BeginInvoke.

Dưới đây là mã của tôi:

using System.Linq; 
using System.Windows.Forms; 

namespace ToggleCheckedListBoxSelection 
{ 
    public partial class Form1 : Form 
    { 
     // default value of -1 since first item index is always 0 
     private int lastIndex = -1; 

     public Form1() 
     { 
      InitializeComponent(); 
      CheckedListBox clb = new CheckedListBox(); 
      clb.Items.AddRange(Enumerable.Range(1, 10).Cast<object>().ToArray()); 
      clb.MouseClick += clb_MouseClick; 
      this.Controls.Add(clb); 
     } 

     private void clb_MouseClick(object sender, MouseEventArgs e) 
     { 
      var clb = (CheckedListBox)sender; 
      Toggle(clb); 

      // call toggle method again if user is trying to toggle the same item they were last on 
      // this solves the issue where calling it once leaves it unchecked 
      // comment these 2 lines out to reproduce issue (use a single click, not a double click) 
      if (lastIndex == clb.SelectedIndex) 
       Toggle(clb); 

      lastIndex = clb.SelectedIndex; 
     } 

     private void Toggle(CheckedListBox clb) 
     { 
      clb.SetItemChecked(clb.SelectedIndex, !clb.GetItemChecked(clb.SelectedIndex)); 
     } 
    } 
} 

Để tái tạo vấn đề nhận xét của tôi ra khỏi dòng đề cập trong các ý kiến ​​mã và làm theo các bước sau:

  1. Nhấp vào mục ở chỉ số 2 - thay đổi trạng thái để đã kiểm tra.
  2. Với mục hiện tại được chọn, hãy nhấp lại vào mục đó - trạng thái không thay đổi. Dự kiến: không được chọn. Nhấp vào nó một vài lần và cuối cùng nó chuyển.

Cảm ơn bạn đã đọc!

Trả lời

49

Là tính năng tiện lợi, tôi cần cho phép người dùng chuyển đổi lựa chọn trong một cú nhấp chuột.

Tôi không chắc chắn những gì đang xảy ra với mã, nhưng thiết CheckOnClick để true sẽ làm điều này:

CheckOnClick cho biết hộp kiểm phải được toggled bất cứ khi nào một mục được chọn. Hành vi mặc định là thay đổi lựa chọn trên lần nhấp đầu tiên và sau đó yêu cầu người dùng nhấp lại để áp dụng dấu kiểm.Tuy nhiên, trong một số trường hợp, bạn có thể muốn có mục được kiểm tra ngay sau khi được nhấp.

+1

+1: Tốt và đơn giản. Bằng cách nào đó tôi đã bỏ qua tùy chọn này. –

+3

Mỏ được đặt thành false theo mặc định khi hành vi tôi muốn là đúng sự thật. cảm ơn vì câu trả lời - nó cũng giúp tôi! – rizalp1

Các vấn đề liên quan