📄 reorderlist.cs
字号:
else
{
// we'll use a table to organize all of this. Set it up.
//
Table itemTable = new Table();
outerItem = itemTable;
itemTable.BorderWidth = 0;
itemTable.CellPadding = 0;
itemTable.CellSpacing = 0;
// we keep track of two cells: one to put the item in,
// on to put the handle in.
//
TableCell itemCell = new TableCell();
itemParent = itemCell;
itemCell.Width = new Unit(100, UnitType.Percentage);
TableCell handleCell = new TableCell();
dragHolder = handleCell;
// based on the alignment value, we set up the cells in the table.
//
switch (DragHandleAlignment)
{
case ReorderHandleAlignment.Left:
case ReorderHandleAlignment.Right:
TableRow r = new TableRow();
if (DragHandleAlignment == ReorderHandleAlignment.Left)
{
r.Cells.Add(handleCell);
r.Cells.Add(itemCell);
}
else
{
r.Cells.Add(itemCell);
r.Cells.Add(handleCell);
}
itemTable.Rows.Add(r);
break;
case ReorderHandleAlignment.Top:
case ReorderHandleAlignment.Bottom:
TableRow itemRow = new TableRow();
TableRow handleRow = new TableRow();
itemRow.Cells.Add(itemCell);
handleRow.Cells.Add(handleCell);
if (DragHandleAlignment == ReorderHandleAlignment.Top)
{
itemTable.Rows.Add(handleRow);
itemTable.Rows.Add(itemRow);
}
else
{
itemTable.Rows.Add(itemRow);
itemTable.Rows.Add(handleRow);
}
break;
}
}
// move the controls into the item cell from the item itself.
//
MoveChildren(item, itemParent);
// create the dragholder
//
ReorderListItem holderItem = new ReorderListItem(item, HtmlTextWriterTag.Div);
DragHandleTemplate.InstantiateIn(holderItem);
dragHolder.Controls.Add(holderItem);
// add the table
//
item.Controls.Add(outerItem);
}
else
{
// otherwise we just create dummy holder (apologies to dummies).
//
Panel holderPanel = new Panel();
MoveChildren(item, holderPanel);
dragHolder = holderPanel;
item.Controls.Add(holderPanel);
}
dragHolder.ID = String.Format(CultureInfo.InvariantCulture, "__dih{0}", item.ItemIndex);
// add the item we created to the draggableItems list.
//
if (_draggableItems == null) _draggableItems = new List<DraggableListItemInfo>();
DraggableListItemInfo dlii = new DraggableListItemInfo();
dlii.TargetControl = item;
dlii.HandleControl = dragHolder;
_draggableItems.Add(dlii);
}
/// <summary>
/// Creates a item at the specified index and binds it to the given data source.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters", Justification = "Assembly is not localized")]
protected virtual ReorderListItem CreateItem(int index, bool dataBind, object dataItem, ListItemType itemType, bool hasDragHandle)
{
// Validate the item type is right.
//
if (itemType != ListItemType.Item && itemType != ListItemType.EditItem && itemType != ListItemType.Separator) throw new ArgumentException("Unknown value", "itemType");
// create the item
//
ReorderListItem item = new ReorderListItem(dataItem, index, itemType);
OnItemCreated(new ReorderListItemEventArgs(item));
// figure out which template to use
//
ITemplate template = ItemTemplate;
if (index == EditItemIndex)
{
template = EditItemTemplate;
}
if (itemType == ListItemType.Separator)
{
template = ReorderTemplate;
}
if (template != null)
{
template.InstantiateIn(item);
}
if (itemType == ListItemType.Item && template == null && dataItem != null && DataSource is IList)
{
// if we don't have a type, and we're bound to an IList, just convert the value.
//
TypeConverter tc = TypeDescriptor.GetConverter(dataItem);
if (tc != null)
{
Label l = new Label();
l.Text = tc.ConvertToString(null, CultureInfo.CurrentUICulture, dataItem);
item.Controls.Add(l);
}
}
// create the drag handle
CreateDragHandle(item);
// add the item and databind it.
//
ChildList.Controls.Add(item);
if (dataBind)
{
item.DataBind();
OnItemDataBound(new ReorderListItemEventArgs(item));
item.DataItem = null;
}
return item;
}
// Perform the actual reorder operation
//
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters", Justification = "Assembly is not localized")]
protected virtual bool DoReorder(int oldIndex, int newIndex)
{
if (IsBoundUsingDataSourceID && SortOrderField != null)
{
DataSourceView dsv = GetData();
EventWaitHandle w = new System.Threading.EventWaitHandle(false, EventResetMode.AutoReset);
bool success = false;
RequiresDataBinding = true;
try
{
// get the data that's currently in the database
//
dsv.Select(new DataSourceSelectArguments(),
delegate(IEnumerable dataSource)
{
success = DoReorderInternal(dataSource, oldIndex, newIndex, dsv);
w.Set();
}
);
w.WaitOne();
// wait for the select to finish - this makes an async operation look
// like a synchronous one.
//
}
catch (Exception ex)
{
CallbackResult = ex.Message;
throw;
}
return success;
}
else if (DataSource is DataTable || DataSource is DataView)
{
DataTable dt = DataSource as DataTable;
if (dt == null)
{
dt = ((DataView)DataSource).Table;
}
return DoReorderInternal(dt , oldIndex, newIndex);
}
else if (DataSource is IList && !((IList)DataSource).IsReadOnly)
{
IList ds = (IList)DataSource;
object value = ds[oldIndex];
if (oldIndex > newIndex)
{
for (int i = oldIndex; i > newIndex; i--)
{
// copy all the items up
ds[i] = ds[i - 1];
}
}
else
{
for (int i = oldIndex; i < newIndex; i++)
{
ds[i] = ds[i + 1];
}
}
ds[newIndex] = value;
return true;
}
return false;
}
/// <summary>
/// Reorder row [oldIndex] to position [newIndex] in a datatable.
/// </summary>
/// <param name="dataSource"></param>
/// <param name="oldIndex"></param>
/// <param name="newIndex"></param>
/// <returns></returns>
private bool DoReorderInternal(DataTable dataSource, int oldIndex, int newIndex)
{
if (String.IsNullOrEmpty(SortOrderField))
{
return false;
}
int start = Math.Min(oldIndex, newIndex);
int end = Math.Max(oldIndex, newIndex);
string filter = String.Format(CultureInfo.InvariantCulture, "{0} >= {1} AND {0} <= {2}", SortOrderField, start, end);
DataRow[] rows = dataSource.Select(filter, SortOrderField + " ASC");
DataColumn column = dataSource.Columns[SortOrderField];
object newValue = rows[newIndex - start][column];
// reorder the list to reflect the new sort.
//
if (oldIndex > newIndex)
{
for (int i = 0; i < rows.Length - 1; i++)
{
rows[i][column] = rows[i+1][column];
}
}
else
{
for (int i = rows.Length -1; i > 0; i--)
{
rows[i][column] = rows[i-1][column];
}
}
rows[oldIndex - start][column] = newValue;
// commit the changes.
//
dataSource.AcceptChanges();
return true;
}
/// <summary>
/// Does the real work of the reorder. It moves the item from oldIndex to newIndex in the given data source.
/// </summary>
/// <param name="dataSource">The datasource this list is bound to</param>
/// <param name="oldIndex">The original index of the item that we're reordering</param>
/// <param name="newIndex">The designation index</param>
/// <param name="dsv">The DataSourceView associated with this control</param>
/// <returns></returns>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes", Justification="Avoiding breaking change")]
private bool DoReorderInternal(IEnumerable dataSource, int oldIndex, int newIndex, DataSourceView dsv)
{
string sortField = SortOrderField;
// get the values for each row that we'll be modifying.
//
List<IOrderedDictionary> valuesList = new List<IOrderedDictionary>(Math.Abs(oldIndex - newIndex));
int start = Math.Min(oldIndex, newIndex);
int end = Math.Max(oldIndex, newIndex);
// nothing to do!
//
if (start == end)
{
return false;
}
int i = 0;
foreach (object row in dataSource)
{
try
{
if (i < start)
{
continue;
}
if (i > end)
{
break;
}
IOrderedDictionary values = new OrderedDictionary();
IDictionary keys = new Hashtable();
PropertyDescriptorCollection props = TypeDescriptor.GetProperties(row);
foreach (PropertyDescriptor p in props)
{
object value = p.GetValue(row);
// convert DBNulls to Null (See Issue 5900)
if (p.PropertyType.IsValueType && value == DBNull.Value)
{
value = null;
}
values[p.Name] = value;
if (p.Name == DataKeyField)
{
keys[p.Name] = values[p.Name];
values.Remove(p.Name);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -