2011-06-08 29 views
2

這裏有一個問題:我有一個Windows窗體我開發的應用程序,並在一個段我使用ListView控件。的ListView ItemChanged拼圖消息框 - ItemSelectionChanged叫了兩聲

我正在嘗試可以簡單地陳述爲:在事件ListViewItemSelectionChange顯示一個MessageBox用戶確認更改,如果沒有確認更改,讓我們說第一個項目。對第一項的更改將再次觸發ListViewItemSelecionChange,因此我取消註冊並重新註冊事件處理程序方法,所以一切都應該很好,對不對?

實際發生的是,該處理方法被調用兩次(實際上ListView應該解僱選擇更改兩個事件,一個是取消選擇,其餘爲新選擇的項目,但我在開始時只捕獲選擇的項目有一個e.IsSelected聲明,所以實際上你可以說有四個事件被解僱)。

的問題是,如果我生成與ListView項鼠標點擊第一個事件,我編程改變的第一個項目,是什麼產生了第二個事件觸發之前已經退訂?由於MessageBox調用它是否有一些焦點更改?有什麼辦法可以防止第二次事件發生?

我在這裏有一個簡單的例子的解決方案,它不能被更多的運動簡化(25 SLOC),所以如果可以的話,請看一看。請注意,註釋行「if(ShowMessageBox())」會阻止第二個事件觸發,這是否是一些焦點更改問題?

http://www.filedropper.com/listviewtestwithmsgbox

編輯:相關代碼:

private void listViewWithSelection1_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e) 
{ 
    // listview actually generates two ItemSelectionChanged events, 
    // one for deselect of a item, and another event for a newly selected item (which we want here). 
    if (e.IsSelected) 
    { 
     if (ShowMessageBox()) 
      Button1_Click(null, EventArgs.Empty); 

     label1.Text += "item selected "; 
    } 
} 

private bool ShowMessageBox() 
{ 
    return MessageBox.Show("Change to first item instead?", "test", MessageBoxButtons.YesNo) == DialogResult.Yes; 
} 

private void Button1_Click(object sender, EventArgs e) 
{ 
    // change ti first ListView item 
    listView1.ItemSelectionChanged -= listViewWithSelection1_ItemSelectionChanged; 
    listView1.Items[0].Selected = true; 
    listView1.ItemSelectionChanged += listViewWithSelection1_ItemSelectionChanged; 
} 
+0

請僅在您的問題中發佈相關代碼,但沒有人想要通過您的解決方案進行瀏覽。 – mdm 2011-06-08 15:36:00

+0

你是對的,我只是想讓它變得簡單,如果有人想嘗試這種方式而沒有創建解決方案的麻煩 – 2011-06-08 15:38:47

回答

1

嗯,你能描述如何選擇正在改變,開始用?如果用戶點擊選擇一個項目,可能會捕獲Click或DoubleClick事件而不是ItemSelectionChanged事件?我目前在程序中使用了這個片段。如果用戶雙擊列表框(在您的情況下爲listView),請對所選項目執行一些操作。

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private bool ShowMessageBox() 
    { 
     return MessageBox.Show("Change to first item instead?", "test", MessageBoxButtons.YesNo) == DialogResult.Yes; 
    } 

    private void listView1_Click(object sender, EventArgs e) 
    { 
     if (ShowMessageBox()) 
      listView1.TopItem.Selected = true; 
      label1.Text += "item selected "; 
    } 
} 

修改爲包含相關代碼。

+0

事件是通過單擊ListView中的項目生成的 – 2011-06-08 15:46:52

+1

試試這個:http:// pastebin。 com/4P50vcEF 工作對我來說非常好。 – Omega192 2011-06-08 18:25:00

+0

是的,這實際上比ItemSelectedChanged制定出更好的,太糟糕了,焦點搞砸了的ListView:/ 謝謝! – 2011-06-09 06:51:40

1

一種方式做到這一點是有一個標誌,該標誌表示應該在上改變代碼運行。

在你ListViewItemSelecionChange代碼,你檢查標誌的值,並相應地運行代碼。

+0

是的,但這更像是一種解決方案和理解問題的「黑客」......這不是「在這裏有一些生產代碼,實際的問題是在一個MVC WinForms應用程序(監督控制器模式)中,我在ListView項目更改上發信號給控制器,進而決定做什麼;當我在兩者之間得到MessageBox時,我得到兩個生成的事件。目前,我已經用這樣的黑客解決了這個問題,但我真的想知道爲什麼會發生這種情況:) – 2011-06-08 15:43:20