这是一个简单的过程吗?
我只是为内部工具编写一个快速的hacky UI。
我不想花一点时间。
答案 0 :(得分:77)
这是一个快速下来的脏应用程序。基本上我用一个按钮和一个ListBox创建了一个Form。单击按钮时,ListBox将填充接下来20天的日期(必须使用仅用于测试的内容)。然后,它允许在ListBox中拖放以进行重新排序:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.listBox1.AllowDrop = true;
}
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i <= 20; i++)
{
this.listBox1.Items.Add(DateTime.Now.AddDays(i));
}
}
private void listBox1_MouseDown(object sender, MouseEventArgs e)
{
if (this.listBox1.SelectedItem == null) return;
this.listBox1.DoDragDrop(this.listBox1.SelectedItem, DragDropEffects.Move);
}
private void listBox1_DragOver(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Move;
}
private void listBox1_DragDrop(object sender, DragEventArgs e)
{
Point point = listBox1.PointToClient(new Point(e.X, e.Y));
int index = this.listBox1.IndexFromPoint(point);
if (index < 0) index = this.listBox1.Items.Count-1;
object data = e.Data.GetData(typeof(DateTime));
this.listBox1.Items.Remove(data);
this.listBox1.Items.Insert(index, data);
}
答案 1 :(得分:6)
晚了7年。但对于任何新人来说,这是代码。
private void listBox1_MouseDown(object sender, MouseEventArgs e)
{
if (this.listBox1.SelectedItem == null) return;
this.listBox1.DoDragDrop(this.listBox1.SelectedItem, DragDropEffects.Move);
}
private void listBox1_DragOver(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Move;
}
private void listBox1_DragDrop(object sender, DragEventArgs e)
{
Point point = listBox1.PointToClient(new Point(e.X, e.Y));
int index = this.listBox1.IndexFromPoint(point);
if (index < 0) index = this.listBox1.Items.Count - 1;
object data = listBox1.SelectedItem;
this.listBox1.Items.Remove(data);
this.listBox1.Items.Insert(index, data);
}
private void itemcreator_Load(object sender, EventArgs e)
{
this.listBox1.AllowDrop = true;
}
答案 2 :(得分:3)
如果你从未实施过拖放,第一次需要几个小时,想要正确完成并且必须阅读文档。特别是如果用户取消操作,立即反馈和恢复列表需要一些想法。将行为封装到可重用的用户控件中也需要一些时间。
如果您从未完成拖放操作,请查看MSDN中的drag and drop example。这将是一个很好的起点,它可能需要半天时间让事情发挥作用。
答案 3 :(得分:0)
另一种方法是使用the list-view控件,这是控件资源管理器用来显示文件夹的内容。它更复杂,但实现了项目拖动。
答案 4 :(得分:0)
这依赖于@BFree的以上回答-非常有帮助。
尝试使用该解决方案时遇到错误,因为我在列表框中使用了数据源。仅出于完整性考虑,如果尝试直接将项目删除或添加到列表框中,则会出现此错误:
// Causes error
this.listBox1.Items.Remove(data);
错误: System.ArgumentException:'设置了DataSource属性时,不能修改Item集合。'
解决方案:更新数据源本身,然后重新绑定到您的列表框。 Program.SelectedReports是一个BindingList。
代码:
private void listboxSelectedReports_DragDrop(object sender, DragEventArgs e)
{
// Get the point where item was dropped.
Point point = listboxSelectedReports.PointToClient(new Point(e.X, e.Y));
// Get the index of the item where the point was dropped
int index = this.listboxSelectedReports.IndexFromPoint(point);
// if index is invalid, put item at the end of the list.
if (index < 0) index = this.listboxSelectedReports.Items.Count - 1;
// Get the item's data.
ReportModel data = (ReportModel)e.Data.GetData(typeof(ReportModel));
// Update the property we use to control sorting within the original datasource
int newSortOrder = 0;
foreach (ReportModel report in Program.SelectedReports) {
// match sorted item on unique property
if (data.Id == report.Id)
{
report.SortOrder = index;
if (index == 0) {
// only increment our new sort order if index is 0
newSortOrder += 1;
}
} else {
// skip our dropped item's index
if (newSortOrder == index) {
newSortOrder += 1;
}
report.SortOrder = newSortOrder;
newSortOrder += 1;
}
}
// Sort original list and reset the list box datasource.
// Note: Tried other things, Reset(), Invalidate(). Updating DataSource was only way I found that worked??
Program.SelectedReports = new BindingList<ReportModel>(Program.SelectedReports.OrderBy(x => x.SortOrder).ToList());
listboxSelectedReports.DataSource = Program.SelectedReports;
listboxSelectedReports.DisplayMember = "Name";
listboxSelectedReports.ValueMember = "ID";
}
其他说明: BindingList在此命名空间下:
using System.ComponentModel;
将项目动态添加到列表时,请确保您填充了排序属性。我使用了整数字段“ SortOrder”。
删除项目时,我不必担心更新Sorting属性,因为它会创建一个数字间隔,在我的情况下,YMMV是可以的。
说实话,除了foreach循环之外,还有一种更好的排序算法,但是在我的情况下,我处理的项目数量非常有限。