Ich habe ein ListBox1-Objekt und es enthält einige Elemente. Ich habe eine Schaltfläche, um das ausgewählte Element nach oben zu verschieben, und eine weitere, um das ausgewählte Element nach unten zu verschieben. Wie lautet der Code für die beiden Tasten?
private void UpClick()
{
// only if the first item isn't the current one
if(listBox1.ListIndex > 0)
{
// add a duplicate item up in the listbox
listBox1.AddItem(listBox1.Text, listBox1.ListIndex - 1);
// make it the current item
listBox1.ListIndex = (listBox1.ListIndex - 2);
// delete the old occurrence of this item
listBox1.RemoveItem(listBox1.ListIndex + 2);
}
}
private void DownClick()
{
// only if the last item isn't the current one
if((listBox1.ListIndex != -1) && (listBox1.ListIndex < listBox1.ListCount - 1))
{
// add a duplicate item down in the listbox
listBox1.AddItem(listBox1.Text, listBox1.ListIndex + 2);
// make it the current item
listBox1.ListIndex = listBox1.ListIndex + 2;
// delete the old occurrence of this item
listBox1.RemoveItem(listBox1.ListIndex - 2);
}
}
public void MoveUp()
{
MoveItem(-1);
}
public void MoveDown()
{
MoveItem(1);
}
public void MoveItem(int direction)
{
// Checking selected item
if (listBox1.SelectedItem == null || listBox1.SelectedIndex < 0)
return; // No selected item - nothing to do
// Calculate new index using move direction
int newIndex = listBox1.SelectedIndex + direction;
// Checking bounds of the range
if (newIndex < 0 || newIndex >= listBox1.Items.Count)
return; // Index out of range - nothing to do
object selected = listBox1.SelectedItem;
// Removing removable element
listBox1.Items.Remove(selected);
// Insert it in new position
listBox1.Items.Insert(newIndex, selected);
// Restore selection
listBox1.SetSelected(newIndex, true);
}
Haben Sie versucht, es in Google zu suchen? Elemente im Listenfeldsteuerelement nach oben/unten verschieben zum Beispiel.
public class SmartListBox : ListBox
{
//Moves the selected items up one level
public MoveUp()
{
for(int i = 0; i < Items.Count; i++)
{
if (Items[i].Selected)//identify the selected item
{
//swap with the top item(move up)
if (i > 0 && !Items[i - 1].Selected)
{
ListItem bottom = Items[i];
Items.Remove(bottom);
Items.Insert(i - 1, bottom);
Items[i - 1].Selected = true;
}
}
}
}
//Moves the selected items one level down
public MoveDown()
{
int startindex = Items.Count -1;
for (int i = startindex; i > -1; i--)
{
if (Items[i].Selected)//identify the selected item
{
//swap with the lower item(move down)
if (i < startindex && !Items[i + 1].Selected)
{
ListItem bottom = Items[i];
Items.Remove(bottom);
Items.Insert(i + 1, bottom);
Items[i + 1].Selected = true;
}
}
}
}
}
@Save-Code wurde geändert, um das Verschieben von Elementen zu ermöglichen, bei denen es sich um Daten handelt, die mit DataSource-Eigenschaften an eine ListBox gebunden sind.
public void MoveItem(int direction)
{
// Checking selected item
if (listBox1.SelectedItem == null || listBox1.SelectedIndex < 0)
return; // No selected item - nothing to do
// Calculate new index using move direction
int newIndex = listBox1.SelectedIndex + direction;
// Checking bounds of the range
if (newIndex < 0 || newIndex >= listBox1.Items.Count)
return; // Index out of range - nothing to do
UnifyCamera selected = listBox1.SelectedItem as UnifyCamera;
// modify the data source list
inputData.Cameras.RemoveAt(listBox1.SelectedIndex);
inputData.Cameras.Insert(newIndex, selected);
// re-bind your data source
((ListBox)listBox1).DataSource = null;
((ListBox)listBox1).DataSource = this.inputData.Cameras;
((ListBox)listBox1).DisplayMember = "Name";
// Restore selection
listBox1.SetSelected(newIndex, true);
}
Dabei ist UnifyCamera
meine benutzerdefinierte Klasse, die in einer Liste inputData.Cameras
gespeichert ist, die einen List<UnifyCamera>
zurückgibt.
Desolator-Code oben wurde geändert, um die Steuerung als Parameter ... weiterzugeben
private void MoveUp()
{
MoveItem(-1,listBox1);
}
private void MoveDown()
{
MoveItem(1,listBox1);
}
public void MoveItem(int direction,ListBox listBox)
{
// Checking selected item
if (listBox.SelectedItem == null || listBox.SelectedIndex < 0)
return; // No selected item - nothing to do
// Calculate new index using move direction
int newIndex = listBox.SelectedIndex + direction;
// Checking bounds of the range
if (newIndex < 0 || newIndex >= listBox.Items.Count)
return; // Index out of range - nothing to do
object selected = listBox.SelectedItem;
// Removing removable element
listBox.Items.Remove(selected);
// Insert it in new position
listBox.Items.Insert(newIndex, selected);
// Restore selection
listBox.SetSelected(newIndex, true);
}
Die Antwort von Vexe funktionierte am besten für mich, aber ich musste sie ändern, um ein paar Probleme zu beheben. Diese Lösung hebt das richtige Objekt hervor, wenn sich dasselbe Objekt mehrmals im Listenfeld befindet. Diese Lösung verhindert auch, dass mehrere ausgewählte Objekte umgedreht werden, wenn sie oben oder unten im Listenfeld angezeigt werden und die Schaltfläche weiterhin mehrfach gedrückt wird.
private void btnMoveUp_Click(object sender, EventArgs e)
{
// find the lowest index of non selected items
int lowestIndexNotSelected = listBox.Items.Count - 1;
for (int i = listBox.Items.Count - 1; i >= 0; i--)
{
if (!listBox.SelectedIndices.Contains(i))
{
lowestIndexNotSelected = i;
}
}
listBox.BeginUpdate();
int numberOfSelectedItems = listBox.SelectedItems.Count;
for (int i = 0; i < numberOfSelectedItems; i++)
{
// only if it's not a lower inde than the lowest non selected index
if (listBox.SelectedIndices[i] > lowestIndexNotSelected)
{
// the index of the item above the item that we wanna move up
int indexToInsertIn = listBox.SelectedIndices[i] - 1;
// insert UP the item that we want to move up
listBox.Items.Insert(indexToInsertIn, listBox.SelectedItems[i]);
// removing it from its old place
listBox.Items.RemoveAt(indexToInsertIn + 2);
// highlighting it in its new place (by index, to prevent highlighting wrong instance)
listBox.SelectedIndex = indexToInsertIn;
}
}
listBox.EndUpdate();
}
private void btnMoveDown_Click(object sender, EventArgs e)
{
// find the highest index of non selected items
int highestIndexNonSelected = 0;
for (int i = 0; i < listBox.Items.Count; i++)
{
if (!listBox.SelectedIndices.Contains(i))
{
highestIndexNonSelected = i;
}
}
listBox.BeginUpdate();
int numberOfSelectedItems = listBox.SelectedItems.Count;
// when going down, instead of moving through the selected items from top to bottom
// we'll go from bottom to top, it's easier to handle this way.
for (int i = numberOfSelectedItems - 1; i >= 0; i--)
{
// only if it's not a higher index than the highest index not selected
if (listBox.SelectedIndices[i] < highestIndexNonSelected)
{
// the index of the item that is currently below the selected item
int indexToInsertIn = listBox.SelectedIndices[i] + 2;
// insert DOWN the item that we want to move down
listBox.Items.Insert(indexToInsertIn, listBox.SelectedItems[i]);
// removing it from its old place
listBox.Items.RemoveAt(indexToInsertIn - 2);
// highlighting it in its new place (by index, to prevent highlighting wrong instance)
listBox.SelectedIndex = indexToInsertIn - 1;
}
}
listBox.EndUpdate();
}
Alle anderen Antworten sind in Ordnung, aber Sie sollten auch diese in Betracht ziehen:) Die Idee davon kommt der von SwDevMan81 sehr nahe, aber dies ist echter Code (nicht Pseudo) (mehrere ausgewählte Elemente) und mit einer Verbesserung beim Abwärtsfahren.
private void MoveUp_listBox_button_Click(object sender, EventArgs e)
{
listBox.BeginUpdate();
int numberOfSelectedItems = listBox.SelectedItems.Count;
for (int i = 0; i < numberOfSelectedItems; i++)
{
// only if it's not the first item
if (listBox.SelectedIndices[i] > 0)
{
// the index of the item above the item that we wanna move up
int indexToInsertIn = listBox.SelectedIndices[i] - 1;
// insert UP the item that we want to move up
listBox.Items.Insert(indexToInsertIn, listBox.SelectedItems[i]);
// removing it from its old place
listBox.Items.RemoveAt(indexToInsertIn + 2);
// highlighting it in its new place
listBox.SelectedItem = listBox.Items[indexToInsertIn];
}
}
listBox.EndUpdate();
}
private void MoveDown_listBox_button_Click(object sender, EventArgs e)
{
listBox.BeginUpdate();
int numberOfSelectedItems = listBox.SelectedItems.Count;
// when going down, instead of moving through the selected items from top to bottom
// we'll go from bottom to top, it's easier to handle this way.
for (int i = numberOfSelectedItems-1; i >= 0; i--)
{
// only if it's not the last item
if (listBox.SelectedIndices[i] < listBox.Items.Count - 1)
{
// the index of the item that is currently below the selected item
int indexToInsertIn = listBox.SelectedIndices[i] + 2;
// insert DOWN the item that we want to move down
listBox.Items.Insert(indexToInsertIn, listBox.SelectedItems[i]);
// removing it from its old place
listBox.Items.RemoveAt(indexToInsertIn - 2);
// highlighting it in its new place
listBox.SelectedItem = listBox.Items[indexToInsertIn - 1];
}
}
listBox.EndUpdate();
}
public static void MoveUpOrDownSelectedItem(ListBox LisBox, bool MoveUp)
{
if (LisBox.SelectedIndex > 0 && MoveUp)
{
// add a duplicate item up in the listbox
LisBox.Items.Insert(LisBox.SelectedIndex - 1, LisBox.SelectedItem);
// make it the current item
LisBox.SelectedIndex = (LisBox.SelectedIndex - 2);
// delete the old occurrence of this item
LisBox.Items.RemoveAt(LisBox.SelectedIndex + 2);
}
if ((LisBox.SelectedIndex != -1) && (LisBox.SelectedIndex < LisBox.Items.Count- 1) && MoveUp == false)
{
// add a duplicate item down in the listbox
int IndexToRemove = LisBox.SelectedIndex;
LisBox.Items.Insert(LisBox.SelectedIndex + 2, LisBox.SelectedItem);
// make it the current item
LisBox.SelectedIndex = (LisBox.SelectedIndex + 2);
// delete the old occurrence of this item
LisBox.Items.RemoveAt(IndexToRemove);
}
}
// Options is a list box
private void MoveUpButton_Click(object sender,EventArgs e) {
int index = Options.SelectedIndex;
if (index <= 0) return;
string item = (string)Options.Items[index - 1];
Options.Items.RemoveAt(index - 1);
Options.Items.Insert(index,item);
selectedIndexChanged(null,null);
}
private void MoveDnButton_Click(object sender,EventArgs e) {
int index = Options.SelectedIndex;
if (index + 1 >= Options.Items.Count) return;
string item = (string)Options.Items[index];
Options.Items.RemoveAt(index);
Options.Items.Insert(index + 1,item);
Options.SelectedIndex = index + 1;
}
// sent when user makes a selection or when he moves an item up or down
private void selectedIndexChanged(object sender,EventArgs e) {
int index = Selected.SelectedIndex;
MoveUpButton.Enabled = index > 0;
MoveDnButton.Enabled = index + 1 < Selected.Items.Count;
}
private void btnUp_Click(object sender, System.EventArgs e)
{
if (this.lbItems.SelectedIndex == -1 || this.lbItems.SelectedIndex == 0)
return;
Object select, previous, temp;
select = lbItems.Items[lbItems.SelectedIndex];
previous = lbItems.Items[lbItems.SelectedIndex-1];
temp = select;
select = previous;
previous = temp;
lbItems.Items[lbItems.SelectedIndex] = select;
lbItems.Items[lbItems.SelectedIndex-1] = previous;
lbItems.SelectedIndex--;
}
private void btnDown_Click(object sender, System.EventArgs e)
{
if (this.lbItems.SelectedIndex == -1 || this.lbItems.SelectedIndex == lbItems.Items.Count-1)
return;
Object select, next, temp;
select = lbItems.Items[lbItems.SelectedIndex];
next = lbItems.Items[lbItems.SelectedIndex+1];
temp = select;
select = next;
next = temp;
lbItems.Items[lbItems.SelectedIndex] = select;
lbItems.Items[lbItems.SelectedIndex+1] = next;
lbItems.SelectedIndex++;
}
Für diejenigen, die nach einer generischen Möglichkeit suchen, mit ListBox umzugehen, die an eine DataSource gebunden sein könnte, ist hier eine generische Erweiterung basierend auf Antwort von Save , die reguläre und gebundene ListBox behandelt.
public static void MoveUp(this ListBox listBox)
{
listBox.MoveItem(-1);
}
public static void MoveDown(this ListBox listBox)
{
listBox.MoveItem(1);
}
public static void MoveItem(this ListBox listBox, int direction)
{
// Checking selected item
if (listBox.SelectedItem == null || listBox.SelectedIndex < 0)
return; // No selected item - nothing to do
// Calculate new index using move direction
int newIndex = listBox.SelectedIndex + direction;
// Checking bounds of the range
if (newIndex < 0 || newIndex >= listBox.Items.Count)
return; // Index out of range - nothing to do
//Find our if we're dealing with a BindingSource
bool isBindingSource = listBox.DataSource is BindingSource;
//Get the list
System.Collections.IList list = isBindingSource ? ((BindingSource)listBox.DataSource).List : listBox.Items;
object selected = listBox.SelectedItem;
// Removing removable element
list.Remove(selected);
// Insert it in new position
list.Insert(newIndex, selected);
// Restore selection
listBox.SetSelected(newIndex, true);
if (isBindingSource)
{
//Reset the binding if needed
((BindingSource)listBox.DataSource).ResetBindings(false);
}
}
Ich verwende dies mit mehreren Auswahlen ..__ und funktioniert auch mit verschachtelten Auswahlen.
private void Order_buttons_Click(object sender, EventArgs e)
{
//If noselection return
if (Layouts_listBox.SelectedItems.Count == 0) return;
//Determines wether up or down
int movement = (sender as Button) == Order_Upbutton? - 1 : 1;
//creates a dictionary associating the original Index (ListBox) to the text
Dictionary<int, string> Items = new Dictionary<int, string>();
//Also creates a list with the Index for sorting
List<int> DesiredOrder = new List<int>();
//Cycle through the selection and fill both the list and dictionary
ListBox.SelectedObjectCollection NN = Layouts_listBox.SelectedItems;
foreach (object n in NN)
{
DesiredOrder.Add(Layouts_listBox.Items.IndexOf(n));
Items.Add(Layouts_listBox.Items.IndexOf(n), (string)n);
}
//Sort the List according to the desired button (Up or Down)
DesiredOrder.Sort();
if ((sender as Button) != Order_Upbutton) DesiredOrder.Reverse();
//I'm using this ErrorHandling but thats up to you
try
{
//Call the MoveItem (Credits to Save) according to the sorted order
foreach (int n in DesiredOrder) MoveItem(movement, Items[n]);
}
catch (Exception)
{
SystemSounds.Asterisk.Play();
}
}
public void MoveItem(int direction, string Selected)
{
// Checking selected item
if (!Layouts_listBox.Items.Contains(Selected) || Layouts_listBox.Items.IndexOf(Selected) < 0)
throw new System.Exception(); // No selected item - Cancel entire Func
// Calculate new index using move direction
int newIndex = Layouts_listBox.Items.IndexOf(Selected) + direction;
// Checking bounds of the range
if (newIndex < 0 || newIndex >= Layouts_listBox.Items.Count)
throw new System.Exception(); // Index out of range - Cancel entire Func
object selected = Layouts_listBox.Items[Layouts_listBox.Items.IndexOf(Selected)];
// Removing removable element
Layouts_listBox.Items.Remove(selected);
// Insert it in new position
Layouts_listBox.Items.Insert(newIndex, selected);
// Restore selection
Layouts_listBox.SetSelected(newIndex, true);
}
Holen Sie sich eine Sammlung der ausgewählten Elemente und verschieben Sie sie wie folgt:
private void btnMoveUp_Click(object sender, EventArgs e)
{
HashSet<KeyValuePair<int, object>> ItemsToMove = new HashSet<KeyValuePair<int, object>>();
foreach (object o in lstMyListView.SelectedItems)
ItemsToMove.Add(new KeyValuePair<int, object>(lstMyListView.Items.IndexOf(o), o));
foreach (KeyValuePair<int, object> kvp in ItemsToMove)
{
if (kvp.Key > 0) // check if its the first item before moving
{
lstMyListView.Items.Remove(kvp.Value);
lstMyListView.Items.Insert(kvp.Key - 1, kvp.Value);
}
}
}
private void btnMoveDown_Click(object sender, EventArgs e)
{
HashSet<KeyValuePair<int, object>> ItemsToMove = new HashSet<KeyValuePair<int, object>>();
foreach (object o in lstMyListView.SelectedItems)
ItemsToMove.Add(new KeyValuePair<int, object>(lstMyListView.Items.IndexOf(o), o));
foreach (KeyValuePair<int, object> kvp in ItemsToMove)
{
if (kvp.Key < lstMyListView.Items.Count - 1) // check if its the last item before moving
{
lstMyListView.Items.Remove(kvp.Value);
lstMyListView.Items.Insert(kvp.Key + 1, kvp.Value);
}
}
}
Für die Up-Taste:
private void UpBottom_Click(object sender, EventArgs e)
{
//this.Options is ListBox
if (this.Options.SelectedIndex == -1 ||
this.Options.SelectedIndex == 0)
return;
string item, aboveItem;
int itemIndex, aboveItemIndex;
itemIndex = this.Options.SelectedIndex;
aboveItemIndex = this.Options.SelectedIndex - 1;
item = (string)this.Options.Items[itemIndex];
aboveItem = (string)this.Options.Items[aboveItemIndex];
this.Options.Items.RemoveAt(aboveItemIndex);
this.Options.Items.Insert(itemIndex, aboveItem);
}
Für den Abwärtsknopf:
private void DownButton_Click(object sender, EventArgs e)
{
//this.Options is ListBox
if (this.Options.SelectedIndex == -1 ||
this.Options.SelectedIndex >= this.Options.Items.Count)
return;
string item, belowItem;
int itemIndex, belowItemIndex;
itemIndex = this.Options.SelectedIndex;
belowItemIndex = this.Options.SelectedIndex + 1;
if (belowItemIndex >= this.Options.Items.Count)
return;
item = (string)this.Options.Items[itemIndex];
belowItem = (string)this.Options.Items[belowItemIndex];
this.Options.Items.RemoveAt(itemIndex);
this.Options.Items.Insert(belowItemIndex, item);
this.Options.SelectedIndex = belowItemIndex;
}
Ich habe diese Funktion geschrieben, um meine ausgewählten Elemente zu verschieben:
using System.Collections;
using System.Collections.Generic;
private void MoveListboxItems(int step, ListBox lb) {
/* 'step' should be:
* -1 for moving selected items up
* 1 for moving selected items down
* 'lb' is your ListBox
* see examples how to call below this function
*/
try {
// do only something when really an item is selected
if (lb.SelectedIndex > -1) {
// get some needed values - they change while we manipulate the listbox
// but we need them as they was original
IList SelectedItems = lb.SelectedItems;
IList SelectedIndices = lb.SelectedIndices;
// set some default values
int selIndex = -1;
int newIndex = -1;
int selCount = SelectedItems.Count;
int lc = 0;
int mc = 0;
string moveOldValue = string.Empty;
string selectedItemValue = string.Empty;
if (step == 1) {
mc = selCount - 1;
} else {
mc = lc;
}
// enter the loop through the selected items
while (lc < selCount) {
selectedItemValue = string.Empty;
moveOldValue = string.Empty;
try {
// get the item that should get moved
selectedItemValue = SelectedItems[mc].ToString();
selIndex = Convert.ToInt32(SelectedIndices[mc]);
} catch {
selIndex = -1;
}
// gen index for new place
newIndex = selIndex + step;
try {
// get the old value from the place where the item get moved
moveOldValue = lb.Items[newIndex].ToString();
} catch { /* do nothing */ }
try {
if (!String.IsNullOrEmpty(selectedItemValue) && !String.IsNullOrEmpty(moveOldValue) && selIndex != -1 && newIndex != -1 && !lb.SelectedIndices.Contains(newIndex)) {
// move selected item
lb.Items.RemoveAt(newIndex);
lb.Items.Insert(newIndex, selectedItemValue);
// write old value back to the old place from selected item
lb.Items.RemoveAt(selIndex);
lb.Items.Insert(selIndex, moveOldValue);
// hold the moved item selected
lb.SetSelected(newIndex, true);
}
} catch { /* do nothing */ }
lc++;
if (step == 1) {
mc -= step;
} else {
mc = lc;
}
}
}
} catch { /* do nothing */ };
}
// examples how i call the function above
void BtnLbUp_Click(object sender, EventArgs e) {
MoveListboxItems(-1, this.lbMyList);
}
void BtnLbDown_Click(object sender, EventArgs e) {
MoveListboxItems(1, this.lbMyList);
}