2012-06-07 90 views
3

我想在C#中使用多擴展ListBox用戶控件執行以下操作。多擴展列表框選擇問題

假設我有一個項目

item 1 
item 2 
item 3 
item 4 
item 5 

,我選擇第1項和第2項

如果我按按Ctrl +向下鍵,列表框更改

的列表框中
item 3 
item 1 
item 2 
item 4 
item 5 

現在,我得到了完美的算法,但我無法保留選定項目的列表。 按下Ctrl + Down/Up鍵後,所有選中的項目都會被移動,但最後只會選中一個項目 。

我想在按下按鍵後保留所選項目的列表。

我認爲這是因爲默認功能爲Down/Up關鍵爲MultiExtended ListBox

有什麼辦法解決這個問題,而不是使用multisimple列表框和添加更多的功能?

+1

假設它是比較短的,或者你可以修剪下來,發佈您的代碼,增加了這一新功能的移動項目了並按Ctrl +向上/向下時列表下來? –

+0

您可能希望查看ListBox.SelectedItems項目屬性。也許訂閱該ListBox的KeyDown和/或KeyUp事件,並在移動後存儲/恢復所選項目。儘管如此,我還沒有測試過它是否有效。 –

回答

0

我用自己的自主開發的代碼重新創建了您的問題,並且遇到了您遇到的同一問題。

我發現我的問題是在KeyDown事件期間試圖改變數據順序。

我設法通過在完成KeyDown事件後處理訂單更改來實現它。

但是我仍然需要恢復列表框的選擇。

這裏是我的代碼:

public partial class mainForm : Form { 

    delegate void noParamsDelegate(); 
    Stack<noParamsDelegate> methodsToCallWhenIdle = new Stack<noParamsDelegate>(); 

    void application_Idle(object sender, EventArgs e) { 
     if(methodsToCallWhenIdle.Count > 0) { 
      methodsToCallWhenIdle.Pop()(); // Call the deligate at the top of the stack 
     } 
    } 

    public mainForm() { 
     InitializeComponent(); 

     Application.Idle += new EventHandler(application_Idle); 
     bindExampleDataToListBox(); 
     listBox.KeyDown += new KeyEventHandler(listBox_KeyDown); 
    } 

    ListItems boundList = new ListItems(); 

    void listBox_KeyDown(object sender, KeyEventArgs e) { 
     if(e.Control && methodsToCallWhenIdle.Count == 0) { 
      if(e.KeyCode == Keys.Down) { 
      copyOfSelectedItems = createCopyOfSelectedItems(); 
       methodsToCallWhenIdle.Push(moveSelectedDown); 
      } 
      if(e.KeyCode == Keys.Up) { 
       copyOfSelectedItems = this.createCopyOfSelectedItems(); 
       methodsToCallWhenIdle.Push(moveSelectedUp); 
      } 
     } 
    } 

    List<ListItem> copyOfSelectedItems = new List<ListItem>(); 
    void moveSelectedDown() { 
     if(copyOfSelectedItems.Count > 0) { 
      boundList.MoveDown(copyOfSelectedItems); 
      restoreSelection(copyOfSelectedItems); 
     } 
    } 
    void moveSelectedUp() { 
     if(copyOfSelectedItems.Count > 0) { 
      boundList.MoveUp(copyOfSelectedItems); 
      restoreSelection(copyOfSelectedItems); 
     } 
    } 

    void restoreSelection(List<ListItem> selectedItems) { 
     foreach(ListItem item in selectedItems) { 
      listBox.SetSelected(listBox.Items.IndexOf(item), true); 
     } 
    } 

    List<ListItem> createCopyOfSelectedItems() { 
     List<ListItem> result = new List<ListItem>(); 
     foreach(ListItem listItem in listBox.SelectedItems) { 
      result.Add(listItem); 
     } 
     return result; 
    } 

    void bindExampleDataToListBox() { 
     BindingSource bSrc = new BindingSource(); 
     boundList = getExampleData(); 
     bSrc.DataSource = boundList; 
     bSrc.Sort = "OrderValue DESC"; 

     listBox.DataSource = bSrc; 
     listBox.DisplayMember = "TextValue"; 

    } 

    ListItems getExampleData() { 
     ListItems result = new ListItems(); 
     result.Add(new ListItem() { TextValue = "Item 1", OrderValue = 0 }); 
     result.Add(new ListItem() { TextValue = "Item 5", OrderValue = 4 }); 
     result.Add(new ListItem() { TextValue = "Item 3", OrderValue = 2 }); 
     result.Add(new ListItem() { TextValue = "Item 4", OrderValue = 3 }); 
     result.Add(new ListItem() { TextValue = "Item 2", OrderValue = 1 }); 
     return result; 

    } 
} 

我不包括我在執行時listItems和列表項,因爲它們沒有真正的問題做。但是如果你想要一份他們的副本,那就讓我知道。

0

你沒有張貼任何代碼,但調用e.SuppressKeyPress = true;應該使其工作:

void listBox1_KeyDown(object sender, KeyEventArgs e) { 
    if (e.Control && e.KeyCode == Keys.Down) { 
    e.SuppressKeyPress = true; 

    if (listBox1.SelectedIndices.Count > 0 && 
     listBox1.SelectedIndices[listBox1.SelectedIndices.Count - 1] < listBox1.Items.Count-1) { 

     List<int> selected = new List<int>(); 
     for (int i = 0; i < listBox1.SelectedIndices.Count; i++) { 
     selected.Add(listBox1.SelectedIndices[i]); 
     } 
     listBox1.SelectedIndices.Clear(); 

     for (int i = selected.Count - 1; i >= 0; i--) { 
     object listboxItem = listBox1.Items[selected[i] + 1]; 
     listBox1.Items[selected[i] + 1] = listBox1.Items[selected[i]]; 
     listBox1.Items[selected[i]] = listboxItem; 
     listBox1.SelectedIndices.Add(selected[i] + 1); 
     } 
    } 
    } 
}