C# 移动列表框中的最后一个剩余项目
C# moving the last remaining item in a list box
这是一个 Windows 表单应用程序,它连接到服务器,获取表格并将它们转换为 drop create SQL 脚本。有两个列表框,加载初始表列表的 lbSource 和包含用户移动到那里以导出的表的 lbTarget。
出现的问题是,如果我移动最后一个剩余的项目(selIndex = 0)
,没有剩余的项目select (lbTarget.SetSelected(selIndex, true);)
selIndex 得到一个值,但是列表框是空(超出范围)。
我需要 (selIndex >= 0)
的代码到 select 下一个项目,如果它在列表的顶部 (also selIndex = 0)
。
所以我尝试做的是检查是否 (listBox.Items.Count == 0)
,但这似乎不起作用。
这是您单击按钮将 (a) 某些项目从一个列表框移动到另一个列表框时发生的情况的代码。源代码与目标代码相同。
private void cmdTargetToSource_Click(object sender, EventArgs e)
{
//move more than one item
lbTarget.SelectionMode = SelectionMode.MultiSimple;
//sorting the lists
lbSource.Sorted = true;
lbTarget.Sorted = true;
//save the selectedIndex
int selIndex = lbTarget.SelectedIndex;
if (lbTarget.SelectedIndex == -1)
{
return;
}
//moving last entry in listBox sets selIndex higher than lbTarget.Items.Count
if (selIndex < lbTarget.Items.Count)
{
selIndex = selIndex - 1;
}
if (selIndex == -1)
{
selIndex = selIndex + 1;
}
//If there are no items left do nothing
if (lbTarget.Items.Count == 0)
{
return;
}
if (selIndex == lbTarget.Items.Count -2)
{
selIndex = selIndex - 1;
}
MoveListBoxItems(lbTarget, lbSource);
//select next item
if (selIndex >= 0)
{
lbTarget.SetSelected(selIndex, true);
}
//selectionmode back to single selection
lbTarget.SelectionMode = SelectionMode.One;
}
让我们看看:当您在 cmdTargetToSource
上 单击 时,您想要 从 [=14= 移动所有选定的项目 ]到ListBox lbTarget
,对吧?
在那种情况下,首先提取方法:
private static void MoveSelectedItems(ListBox source, ListBox target) {
if (null == source)
throw new ArgumentNullException("source");
else if (null == target)
throw new ArgumentNullException("target");
// Indice to move (Linq)
var indice = source.SelectedIndices.OfType<int>().OrderByDescending(item => item);
// Place to move (at the end of target listbox, if target is not sorted)
int place = target.Items.Count;
// we don't need repaint source as well as target on moving each item
// which cause blinking, so let's stop updating them for the entire operation
source.BeginUpdate();
target.BeginUpdate();
Boolean sorted = target.Sorted;
try {
// switch sorting off so sorting would not change indice
// of items inserted
target.Sorted = false;
// Move items from source to target
foreach (var index in indice) {
target.Items.Insert(place, source.Items[index]);
target.SelectedIndices.Add(place);
source.Items.RemoveAt(index);
}
}
finally {
target.Sorted = true;
target.EndUpdate();
source.EndUpdate();
}
}
然后称之为
private void cmdTargetToSource_Click(object sender, EventArgs e) {
MoveSelectedItems(lbSource, lbTarget);
}
使用提取的方法,如果需要,您可以轻松实现反向移动:
private void cmdBackTargetToSource_Click(object sender, EventArgs e) {
// Just swap source and target:
MoveSelectedItems(lbTarget, lbSource);
}
这是一个 Windows 表单应用程序,它连接到服务器,获取表格并将它们转换为 drop create SQL 脚本。有两个列表框,加载初始表列表的 lbSource 和包含用户移动到那里以导出的表的 lbTarget。
出现的问题是,如果我移动最后一个剩余的项目(selIndex = 0)
,没有剩余的项目select (lbTarget.SetSelected(selIndex, true);)
selIndex 得到一个值,但是列表框是空(超出范围)。
我需要 (selIndex >= 0)
的代码到 select 下一个项目,如果它在列表的顶部 (also selIndex = 0)
。
所以我尝试做的是检查是否 (listBox.Items.Count == 0)
,但这似乎不起作用。
这是您单击按钮将 (a) 某些项目从一个列表框移动到另一个列表框时发生的情况的代码。源代码与目标代码相同。
private void cmdTargetToSource_Click(object sender, EventArgs e)
{
//move more than one item
lbTarget.SelectionMode = SelectionMode.MultiSimple;
//sorting the lists
lbSource.Sorted = true;
lbTarget.Sorted = true;
//save the selectedIndex
int selIndex = lbTarget.SelectedIndex;
if (lbTarget.SelectedIndex == -1)
{
return;
}
//moving last entry in listBox sets selIndex higher than lbTarget.Items.Count
if (selIndex < lbTarget.Items.Count)
{
selIndex = selIndex - 1;
}
if (selIndex == -1)
{
selIndex = selIndex + 1;
}
//If there are no items left do nothing
if (lbTarget.Items.Count == 0)
{
return;
}
if (selIndex == lbTarget.Items.Count -2)
{
selIndex = selIndex - 1;
}
MoveListBoxItems(lbTarget, lbSource);
//select next item
if (selIndex >= 0)
{
lbTarget.SetSelected(selIndex, true);
}
//selectionmode back to single selection
lbTarget.SelectionMode = SelectionMode.One;
}
让我们看看:当您在 cmdTargetToSource
上 单击 时,您想要 从 [=14= 移动所有选定的项目 ]到ListBox lbTarget
,对吧?
在那种情况下,首先提取方法:
private static void MoveSelectedItems(ListBox source, ListBox target) {
if (null == source)
throw new ArgumentNullException("source");
else if (null == target)
throw new ArgumentNullException("target");
// Indice to move (Linq)
var indice = source.SelectedIndices.OfType<int>().OrderByDescending(item => item);
// Place to move (at the end of target listbox, if target is not sorted)
int place = target.Items.Count;
// we don't need repaint source as well as target on moving each item
// which cause blinking, so let's stop updating them for the entire operation
source.BeginUpdate();
target.BeginUpdate();
Boolean sorted = target.Sorted;
try {
// switch sorting off so sorting would not change indice
// of items inserted
target.Sorted = false;
// Move items from source to target
foreach (var index in indice) {
target.Items.Insert(place, source.Items[index]);
target.SelectedIndices.Add(place);
source.Items.RemoveAt(index);
}
}
finally {
target.Sorted = true;
target.EndUpdate();
source.EndUpdate();
}
}
然后称之为
private void cmdTargetToSource_Click(object sender, EventArgs e) {
MoveSelectedItems(lbSource, lbTarget);
}
使用提取的方法,如果需要,您可以轻松实现反向移动:
private void cmdBackTargetToSource_Click(object sender, EventArgs e) {
// Just swap source and target:
MoveSelectedItems(lbTarget, lbSource);
}