在 WPF 列表框中上下移动项目
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12540457/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Moving an item up and down in a WPF list box
提问by DommyCastles
I have a list box with a bunch of values in it. I also have an UP button and a DOWN button. With these buttons, I would like to move the selected item in the list box up/down. I am having trouble doing this.
我有一个列表框,里面有一堆值。我还有一个向上按钮和一个向下按钮。使用这些按钮,我想向上/向下移动列表框中的选定项目。我在做这件事时遇到了麻烦。
Here is my code so far:
到目前为止,这是我的代码:
private void btnDataUp_Click(object sender, RoutedEventArgs e)
{
int selectedIndex = listBoxDatasetValues.SelectedIndex; //get the selected item in the data list
if (selectedIndex != -1 && selectedIndex != 0) //if the selected item is selected and not at the top of the list
{
//swap items here
listBoxDatasetValues.SelectedIndex = selectedIndex - 1; //keep the item selected
}
}
I do not know how to swap the values! Any help would be GREATLY appreciated!
我不知道如何交换值!任何帮助将不胜感激!
回答by Peter Hansen
Since you have populated the listbox by binding to a ObservableCollection using ItemsSource, you cant modify the Items property of the listbox.
由于您已通过使用 ItemsSource 绑定到 ObservableCollection 来填充列表框,因此您无法修改列表框的 Items 属性。
ItemsSource can be set only when the Items collection is empty, and Items can be modified only when ItemsSource is null.
ItemsSource只有在Items集合为空时才能设置,Items只有在ItemsSource为空时才能修改。
Otherwise you will get the error "Operation is not valid while ItemsSource is in use..."
否则,您将收到错误“在使用 ItemsSource 时操作无效...”
What you have to do, is modify the underlying collection, and because it's an ObservableCollection, the ListBox will reflect the changes.
您需要做的是修改底层集合,因为它是一个 ObservableCollection,ListBox 将反映更改。
The following code shows how you can move an item up and down by swapping the item in the collection.
以下代码显示了如何通过交换集合中的项目来上下移动项目。
The corresponding XAML just contains a listbox called lbItems and 2 buttons which hook up the eventhandlers.
相应的 XAML 只包含一个名为 lbItems 的列表框和 2 个连接事件处理程序的按钮。
public partial class MainWindow : Window
{
private ObservableCollection<string> ListItems = new ObservableCollection<string>
{
"Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6"
};
public MainWindow()
{
InitializeComponent();
lbItems.ItemsSource = this.ListItems;
}
private void up_click(object sender, RoutedEventArgs e)
{
var selectedIndex = this.lbItems.SelectedIndex;
if (selectedIndex > 0)
{
var itemToMoveUp = this.ListItems[selectedIndex];
this.ListItems.RemoveAt(selectedIndex);
this.ListItems.Insert(selectedIndex - 1, itemToMoveUp);
this.lbItems.SelectedIndex = selectedIndex - 1;
}
}
private void down_click(object sender, RoutedEventArgs e)
{
var selectedIndex = this.lbItems.SelectedIndex;
if (selectedIndex + 1 < this.ListItems.Count)
{
var itemToMoveDown = this.ListItems[selectedIndex];
this.ListItems.RemoveAt(selectedIndex);
this.ListItems.Insert(selectedIndex + 1, itemToMoveDown);
this.lbItems.SelectedIndex = selectedIndex + 1;
}
}
}
回答by MysticEmpires
I make some extension methods for this:
我为此做了一些扩展方法:
public static void MoveItemUp<T>(this ObservableCollection<T> baseCollection, int selectedIndex)
{
//# Check if move is possible
if (selectedIndex <= 0)
return;
//# Move-Item
baseCollection.Move(selectedIndex - 1, selectedIndex);
}
public static void MoveItemDown<T>(this ObservableCollection<T> baseCollection, int selectedIndex)
{
//# Check if move is possible
if (selectedIndex < 0 || selectedIndex + 1 >= baseCollection.Count)
return;
//# Move-Item
baseCollection.Move(selectedIndex + 1, selectedIndex);
}
public static void MoveItemDown<T>(this ObservableCollection<T> baseCollection, T selectedItem)
{
//# MoveDown based on Item
baseCollection.MoveItemDown(baseCollection.IndexOf(selectedItem));
}
public static void MoveItemUp<T>(this ObservableCollection<T> baseCollection, T selectedItem)
{
//# MoveUp based on Item
baseCollection.MoveItemUp(baseCollection.IndexOf(selectedItem));
}
There is no need to know the ListBox for this.
没有必要为此知道 ListBox。
回答by MangoCrysis
This is the easiest way to do this and it fires all the right events so you don't have to worry about XAML. ObservableCollection has a nice method called
这是执行此操作的最简单方法,它会触发所有正确的事件,因此您不必担心 XAML。ObservableCollection 有一个很好的方法叫做
MoveItem(previousIndex, newIndex)
Given that you have a ObservableCollection named DataItemList
鉴于您有一个名为 DataItemList 的 ObservableCollection
public void MoveUp()
{
var currentIndex = DataItemList.SelectedIndex;
//Index of the selected item
if (currentIndex > 0)
{
int upIndex = currentIndex - 1;
//move the items
DataItemList.MoveItem(upIndex,currentIndex);
}
}
For Down you get the index of the preceding item.
对于 Down,您将获得前一项的索引。
Simple as that!
就那么简单!
回答by Vereos
I would have added a comment, but I can't since I only have 3 reputation :/
我会添加评论,但我不能,因为我只有 3 个声望:/
Peter Hansen's solution is great, but if there isn't a selected element, down_click throws an ArgumentOutOfRange Exception. This is because if there is no element selected, the Index is equal to -1.
Peter Hansen 的解决方案很棒,但如果没有选定元素,则 down_click 会抛出 ArgumentOutOfRange 异常。这是因为如果没有选择元素,则索引等于 -1。
I'd edit down_click like this:
我会像这样编辑 down_click:
private void down_click(object sender, RoutedEventArgs e)
{
if (this.lbItems.SelectedIndex != -1) //Added condition
{
var selectedIndex = this.lbItems.SelectedIndex;
if (selectedIndex + 1 < this.ListItems.Count)
{
var itemToMoveDown = this.ListItems[selectedIndex];
this.ListItems.RemoveAt(selectedIndex);
this.ListItems.Insert(selectedIndex + 1, itemToMoveDown);
this.lbItems.SelectedIndex = selectedIndex + 1;
}
}
}
回答by HasanAboShally
try this:
尝试这个:
if (listBoxDatasetValues.SelectedItems.Count > 0)
{
object selected = listBoxDatasetValues.SelectedItem;
int indx = listBoxDatasetValues.Items.IndexOf(selected);
int totl = listBoxDatasetValues.Items.Count;
if (indx == 0)
{
listBoxDatasetValues.Items.Remove(selected);
listBoxDatasetValues.Items.Insert(totl - 1, selected);
listBoxDatasetValues.SetSelected(totl - 1, true);
}
else{
listBoxDatasetValues.Items.Remove(selected);
listBoxDatasetValues.Items.Insert(indx - 1, selected);
listBoxDatasetValues.SetSelected(indx - 1, true);
}
}
回答by HasanAboShally
if(listBoxDatasetValues.ListIndex > 0)
{
// add a duplicate item up in the listbox
listBoxDatasetValues.AddItem(listBoxDatasetValues.Text, listBoxDatasetValues.ListIndex - 1);
// make it the current item
listBoxDatasetValues.ListIndex = (listBoxDatasetValues.ListIndex - 2);
// delete the old occurrence of this item
listBoxDatasetValues.RemoveItem(listBoxDatasetValues.ListIndex + 2);
}
回答by HasanAboShally
You may try something like this:
你可以尝试这样的事情:
For moving UP:
向上移动:
if (listboxName.SelectedIndex == -1 || listboxName.SelectedIndex == 0)
return;
Object select, previous, temp;
select = listboxName.Items[listboxName.SelectedIndex];
previous = listboxName.Items[listboxName.SelectedIndex-1];
temp = select;
select = previous;
previous = temp;
listboxName.Items[listboxName.SelectedIndex] = select;
listboxName.Items[listboxName.SelectedIndex-1] = previous;
listboxName.SelectedIndex--;
For moving Down:
向下移动:
if (listboxName.SelectedIndex == -1 || listboxName.SelectedIndex == listboxName.Items.Count-1)
return;
Object select, next, temp;
select = listboxName.Items[listboxName.SelectedIndex];
next = listboxName.Items[listboxName.SelectedIndex+1];
temp = select;
select = next;
next = temp;
listboxName.Items[listboxName.SelectedIndex] = select;
listboxName.Items[listboxName.SelectedIndex+1] = next;
listboxName.SelectedIndex++;

