2010-03-31 40 views
14

Có thể hủy sự kiện SelectedIndexChange cho một hộp danh sách trên ứng dụng winforms không? Điều này có vẻ như một điều hợp lý để có được rằng tôi phải được nhìn thấy một số tính năng dễ dàng. Về cơ bản, tôi đã bật lên một hộp thông báo yêu cầu nếu người dùng thực sự muốn chuyển sang một mục khác, vì điều này sẽ thay đổi giao diện người dùng và tôi không muốn thay đổi của họ bị mất. Tôi muốn có thể hủy sự kiện trong trường hợp người dùng chưa lưu những gì họ đang làm việc. Có cách nào tốt hơn để làm điều này?Hủy bỏ ListBox SelectedIndexThay đổi sự kiện

+0

Tôi đồng ý với nawfal để biết thêm chi tiết kiểm tra đường dẫn sau .... http://www.mindstick.com/Articles/176c6d68-ceca-4072-a319-7389f4e5b9dd/?ListBox%20events % 20in% 20C% 20 # .Net –

+0

Bản sao có thể có của [Cách ngăn chặn/hủy thay đổi giá trị của combobox trong C#?] (Http://stackoverflow.com/questions/314503/how-to-prevent-cancel-a- comboboxs-value-change-in-c) –

Trả lời

16

Bạn không thể hủy nó.

Những gì tôi đã làm chỉ một vài ngày trước là có biến với chỉ mục được chọn mới nhất. Sau đó, khi sự kiện cháy, bạn yêu cầu người dùng nếu anh ta muốn lưu, điều này được thực hiện trong eventhandler. Nếu người dùng đã chọn "Hủy", bạn thay đổi lại id.

Vấn đề là điều này sẽ làm cho sự kiện cháy một lần nữa. Vì vậy, những gì tôi đã sử dụng là một bool chỉ nói "Inhibit". Và ở phía trên cùng của eventhandler tôi có:

if(Inhibit) 
    return; 

Sau đó, bên dưới này, nơi bạn đặt câu hỏi bạn làm điều gì đó như thế này:

DialogResult result = MessageBox.Show("yadadadad", yadada cancel etc); 
if(result == DialogResult.Cancel){ 
    Inhibit = true; //Make sure that the event does not fire again 
    list.SelectedIndex = LastSelectedIndex; //your variable 
    Inhibit = false; //Enable the event again 
} 
LastSelectedIndex = list.SelectedIndex; // Save latest index. 
+1

Một biến thể nhỏ về điều này, tôi phát hiện ra sau khi đọc câu trả lời này - bạn có thể loại bỏ trình xử lý sự kiện thay vì sử dụng cờ Inhibit: 'list.SelectedIndexChanged - = list_SelectedIndexChanged; list.SelectedIndex = LastSelectedIndex; list.SelectedIndexChanged + = list_SelectedIndexChanged; ' Có thể có một số lý do mà đây là phương pháp kém hơn, nhưng làm việc rất tốt cho mục đích của tôi. – TwainJ

+0

@J Jones Điều gì xảy ra nếu bạn đã trừ đi hai lần? Bạn không chắc chắn nếu điều đó sẽ không ném một ngoại lệ? –

+0

@OskarKjellin Bạn sẽ không làm điều đó hai lần vì đây là chức năng bên trong.Chức năng sẽ không bao giờ được gọi lại cho đến khi bạn thêm nó trở lại sau. – Grungondola

2

Các SelectedIndexChanged không thể bị hủy bỏ. Vì vậy, bạn chỉ có một tùy chọn thực sự:

private int? currentIndex; 
public void ListBox_SelectedIndexChanged(sender, EventArgs args) { 
    if (currentIndex.HasValue && currentIndex.Value != listBox1.SelectedIndex) { 
     var res = MessageBox.Show("Do you want to cancel edits?", "Cancel Edits", MessageBoxButtons.YesNo); 
     if (res == DialogResult.Yes) { 
      currentIndex = (listBox1.SelectedIndex == -1 ? null : (int?) listBox1.SelectedIndex); 
     } else { 
      listBox1.SelectedIndex = currentIndex.Value; 
     } 
    } 
} 
5

Tôi vừa gặp sự cố chính xác này. Những gì tôi đã làm là khi người dùng thực hiện thay đổi, tôi đặt ListBox.Enabled = false; Điều này không cho phép họ chọn một chỉ mục khác. Một khi họ lưu hoặc loại bỏ các thay đổi của họ, tôi đặt ListBox.Enabled = true; Có lẽ không phải là slick như một dấu nhắc, nhưng nó được công việc làm.

+0

Điều này thật tuyệt vời. Bất cứ lúc nào tôi bắt đầu phải lo lắng về các biến thành viên riêng tư theo dõi chỉ số hiện tại, hoặc theo dõi một số boolean Inhibit, tôi bắt đầu suy nghĩ: làm thế nào tôi có thể tránh thêm lớp logic bổ sung này? Vô hiệu hóa ListBox sẽ quan tâm đến điều đó. – JustLooking

9

Đây chính xác là phương pháp của @Oskar Kjellin, nhưng với một bước ngoặt. Tức là, một biến ít hơn và với một sự thay đổi chỉ mục đã chọn đã thay đổi sự kiện thực sự hoạt động giống như một sự kiện đã thay đổi chỉ mục đã chọn. Tôi thường tự hỏi tại sao chọn chỉ số thay đổi sự kiện bị sa thải ngay cả khi tôi nhấp vào cùng một mục được chọn. Ở đây nó không. Vâng, đó là độ lệch, vì vậy hãy chắc chắn gấp đôi nếu bạn muốn điều này ở đó.

int _selIndex = -1; 
    private void listBox1_SelectedIndexChanged(object sender, EventArgs e) 
    { 
     if (listBox1.SelectedIndex == _selIndex) 
      return; 

     if (MessageBox.Show("") == DialogResult.Cancel) 
     { 
      listBox1.SelectedIndex = _selIndex; 
      return; 
     } 

     _selIndex = listBox1.SelectedIndex; 
     // and the remaining part of the code, what needs to happen when selected index changed happens 
    } 
0

thanh lịch hơn, sử dụng tài sản Tag:

 if ((int)comboBox.Tag == comboBox.SelectedIndex) 
     { 
      // Do Nothing 
     } 
     else 
     { 
      if (MessageBox.Show("") == DialogResult.Cancel) 
      { 
       comboBox.SelectedIndex = (int)comboBox.Tag; 
      } 
      else 
      { 
       // Reset the Tag 
       comboBox.Tag = comboBox.SelectedIndex; 

       // Do what you have to 
      } 
     } 
0

Đây là cách của tôi để hủy SelectionChange cho ComboBox. Tôi nghĩ rằng nó cũng có thể phù hợp với ListBox.

private bool comboBox_CancelSelection = false; 
private int comboBox_LastSelectedIndex = -1; 

private void comboBox_SelectedIndexChanged(object sender, EventArgs e) { 
    if (comboBox_CancelSelection) { 
     comboBox_CancelSelection = false; 
     return ; 
    } 

    // Handle Event 

    if (!comoBox_CancelSelection) { 
     comboBox_LastSelectedIndex = comboBox.SelectedIndex; 
    } else { 
     comboBox.SelectedIndex = comboBox_LastSelectedIndex; 
    } 
} 
Các vấn đề liên quan