2012-06-07 3 views
3

Я пытаюсь сделать следующее с многоэкранным пользовательским элементом управления ListBox на C#.MultiExtended ListBox selection issue

Предположим, у меня есть поле со списком элементов

item 1 
item 2 
item 3 
item 4 
item 5 

и я выбираю пункт 1 и пункт 2.

Если я нажимаю Ctrl + Вниз ключ, изменения списка для

item 3 
item 1 
item 2 
item 4 
item 5 

Теперь у меня алгоритмы работают отлично, но я не могу сохранить список выбранных элементов. После нажатия клавиши Ctrl + Вниз/Вверх Ключ, все выбранные элементы перемещаются, но в конце выбран только один элемент .

Я хочу сохранить список выбранных элементов после нажатия клавиши.

Я думаю, что это из-за функциональности по умолчанию Вниз/вверх ключ для MultiExtended ListBox.

Есть ли способ исправить это, кроме использования многопроцессного списка и добавления дополнительных функций?

+1

Предполагая, что это относительно короткое, или что вы можете обрезать его, разместить свой код, который добавляет эту новую функциональность для перемещения элементов вверх и вниз по списку, когда вы Ctrl + Вверх/Вниз? –

+0

Возможно, вы захотите просмотреть свойство ListBox.SelectedItems. Возможно, подписаться на событие KeyDown и/или KeyUp для этого ListBox и сохранить/восстановить выбранные элементы после их перемещения. Я не проверял это, чтобы увидеть, работает ли это. –

ответ

0

Я воссоздал вашу проблему с помощью своего собственного доморощенного кода, и я столкнулся с той же проблемой, что и у вас.

Я обнаружил, что проблема для меня заключалась в попытке изменить порядок данных во время события KeyDown.

Мне удалось заставить его работать, обработав изменение заказа после завершения события KeyDown.

Мне все еще нужно было восстановить выбор ListBox.

Вот мой код:

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 и ListItem, как они на самом деле делать с этой проблемой. Но если вы хотите их скопировать, просто дайте мне знать.

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); 
     } 
    } 
    } 
}