#region
|
|
using System;
|
using System.Collections;
|
using System.Data;
|
using System.Windows.Forms;
|
using CSFrameworkV5.Core;
|
using DevExpress.XtraGrid.Views.Grid;
|
|
#endregion
|
|
namespace CSFrameworkV5.Library
|
{
|
public partial class frmRowPositionAdjustor : Form
|
{
|
private static Hashtable _HS = new Hashtable();
|
private IRowAdjustor _Adjustor;
|
|
public frmRowPositionAdjustor()
|
{
|
InitializeComponent();
|
}
|
|
private static void AddMenu(GridView gv, string sortFieldName)
|
{
|
//添加分隔条菜单项
|
gv.GridControl.ContextMenuStrip.Items.Add("-");
|
|
//添加菜单项
|
var img = new frmRowPositionAdjustor().imageList1.Images[0];
|
var menuItem =
|
gv.GridControl.ContextMenuStrip.Items.Add("调整行位置", img,
|
On_Adjustor_Click);
|
menuItem.Name = "menuRowAdjustor";
|
menuItem.Tag = new RowAdjustorMenuItemTag
|
{ GridView = gv, SortFieldName = sortFieldName };
|
}
|
|
private void btnFirst_Click(object sender, EventArgs e)
|
{
|
_Adjustor.ToFirst();
|
}
|
|
private void btnLast_Click(object sender, EventArgs e)
|
{
|
_Adjustor.ToLast();
|
}
|
|
private void btnNext_Click(object sender, EventArgs e)
|
{
|
_Adjustor.ToNext();
|
}
|
|
private void btnPrior_Click(object sender, EventArgs e)
|
{
|
_Adjustor.ToPrior();
|
}
|
|
private void btnReset_Click(object sender, EventArgs e)
|
{
|
_Adjustor.Reset();
|
}
|
|
/// <summary>
|
/// 打开排序调整界面
|
/// </summary>
|
/// <param name="owner">父级窗体</param>
|
/// <param name="grid">表格组件</param>
|
/// <param name="sortFieldName">排序字段名称</param>
|
/// <param name="autoClose">自动关闭排序调整窗体,C/S开发框架调用必须设为True,其他调用设为False</param>
|
public static void Execute(Form owner, GridView grid,
|
string sortFieldName, bool autoClose = false)
|
{
|
if (owner == null) throw new Exception("必须指定父级窗体!");
|
|
var form = new frmRowPositionAdjustor();
|
form._Adjustor = new GridViewRowAdjustor(grid, sortFieldName);
|
form.TopMost = true;
|
form.Owner = owner;
|
form.SetPosition(grid);
|
form.Show();
|
|
//自动关闭排序调整窗体
|
if (autoClose)
|
{
|
owner.FormClosing += Owner_FormClosing;
|
owner.Deactivate += Owner_Deactivate;
|
_HS.Add(owner, form);
|
}
|
}
|
|
//关闭当前窗体(Adjustor Form)
|
private void frmRowPositionAdjustor_FormClosed(object sender,
|
FormClosedEventArgs e)
|
{
|
if (_HS.Contains(Owner)) _HS.Remove(Owner);
|
}
|
|
private static void On_Adjustor_Click(object sender, EventArgs e)
|
{
|
var tag = (sender as ToolStripItem).Tag as RowAdjustorMenuItemTag;
|
Execute(tag.GridView.GridControl.FindForm(), tag.GridView,
|
tag.SortFieldName, true);
|
}
|
|
//父级窗体失去焦点事件
|
private static void Owner_Deactivate(object sender, EventArgs e)
|
{
|
if (_HS.Contains(sender as Form))
|
{
|
(_HS[sender as Form] as frmRowPositionAdjustor).Close();
|
_HS.Remove(sender as Form);
|
}
|
}
|
|
//父级窗体关闭事件
|
private static void Owner_FormClosing(object sender,
|
FormClosingEventArgs e)
|
{
|
if (_HS.Contains(sender as Form))
|
{
|
(_HS[sender as Form] as frmRowPositionAdjustor).Close();
|
_HS.Remove(sender as Form);
|
}
|
}
|
|
/// <summary>
|
/// 注册表格组件,自动创建弹出菜单
|
/// </summary>
|
/// <param name="gv">表格组件</param>
|
/// <param name="sortFieldName">排序字段名称</param>
|
public static void Register(GridView gv, string sortFieldName)
|
{
|
var menu = gv.GridControl.ContextMenuStrip;
|
|
if (menu == null)
|
{
|
gv.GridControl.ContextMenuStrip = new ContextMenuStrip();
|
AddMenu(gv, sortFieldName);
|
}
|
else
|
{
|
var items = menu.Items.Find("menuRowAdjustor", true);
|
if (items.Length == 0) AddMenu(gv, sortFieldName);
|
}
|
}
|
|
//设置窗体的显示位置
|
private void SetPosition(GridView grid)
|
{
|
var form = grid.GridControl.FindForm();
|
StartPosition = FormStartPosition.Manual;
|
|
//int X = grid.GridControl.Left + form.Left+150;
|
//int Y = grid.GridControl.Top + form.Top;
|
//this.Location = new Point(X, Y);
|
|
var P = grid.GridControl.PointToScreen(grid.GridControl.Location);
|
P.X += 100;
|
P.Y += 20;
|
Location = P;
|
}
|
}
|
|
public class RowAdjustorMenuItemTag
|
{
|
public GridView GridView { get; set; }
|
|
public string SortFieldName { get; set; }
|
}
|
|
/// <summary>
|
/// 位置调整接口
|
/// </summary>
|
public interface IRowAdjustor
|
{
|
/// <summary>
|
/// 重置排序序号
|
/// </summary>
|
decimal Reset();
|
|
void ToFirst();
|
|
void ToLast();
|
|
void ToNext();
|
|
void ToPrior();
|
}
|
|
/// <summary>
|
/// DevExpress GridView表格记录行位置调整器 - C/S框架网 - www.cscode.net
|
/// </summary>
|
public class GridViewRowAdjustor : IRowAdjustor
|
{
|
private int _FirstSortID = 1; //默认初始序号(第一条记录的序号)
|
private GridView _GridView;
|
private string _SortFieldName; //用于排序的字段名称
|
|
public GridViewRowAdjustor(GridView view, string sortFieldName)
|
{
|
_GridView = view;
|
_SortFieldName = sortFieldName;
|
|
//设置排序字段
|
DataSource.DefaultView.Sort = sortFieldName + " ASC";
|
|
CheckSortValue(true);
|
}
|
|
private DataTable DataSource =>
|
_GridView.GridControl.DataSource as DataTable;
|
|
public decimal Reset()
|
{
|
if (_GridView.RowCount == 0) return 0;
|
|
var i = _FirstSortID; //初始序号
|
|
//枚举DataView的记录,重新设置序号
|
//不能直接枚举DataView.Table对象的记录,这是原始记录
|
DataRow row;
|
var enu = DataSource.DefaultView.GetEnumerator();
|
while (enu.MoveNext())
|
{
|
row = (enu.Current as DataRowView).Row;
|
//跳过被删除的记录
|
if (row.RowState != DataRowState.Deleted)
|
{
|
row[_SortFieldName] = i;
|
i++;
|
}
|
}
|
|
_GridView.GridControl.RefreshDataSource();
|
_GridView.FocusedRowHandle = 0;
|
|
return i;
|
}
|
|
public void ToFirst()
|
{
|
//当前记录是第一条记录,不处理
|
if (_GridView.FocusedRowHandle == 0) return;
|
|
//当前记录
|
var R = _GridView.GetFocusedDataRow();
|
|
//原始第1条记录的序号
|
var R_Old = _GridView.GetDataRow(0);
|
var sort = GetSortValue(R_Old[_SortFieldName]);
|
R[_SortFieldName] = sort / 2; //当前记录的序号=原始第1条记录的序号/2,所以排在前面
|
_GridView.GridControl.RefreshDataSource();
|
}
|
|
public void ToLast()
|
{
|
//当前记录是最后一条记录,不处理
|
if (_GridView.FocusedRowHandle == _GridView.RowCount - 1) return;
|
|
//当前记录
|
var R = _GridView.GetFocusedDataRow();
|
|
//原始最后一条记录的序号
|
var R_Old = _GridView.GetDataRow(_GridView.RowCount - 1);
|
var sort = GetSortValue(R_Old[_SortFieldName]);
|
R[_SortFieldName] = sort + 1; //最后序号+1,排序最后
|
|
_GridView.GridControl.RefreshDataSource();
|
}
|
|
public void ToNext()
|
{
|
//当前记录是最后一条记录,不处理
|
if (_GridView.FocusedRowHandle == _GridView.RowCount - 1) return;
|
|
//当前记录
|
var R1 = _GridView.GetFocusedDataRow();
|
var sort1 = GetSortValue(R1[_SortFieldName]);
|
|
//取下1条记录
|
var R2 = _GridView.GetDataRow(_GridView.FocusedRowHandle + 1);
|
var sort2 = GetSortValue(R2[_SortFieldName]);
|
|
//交换序号
|
R1[_SortFieldName] = sort2;
|
R2[_SortFieldName] = sort1;
|
|
_GridView.GridControl.RefreshDataSource();
|
}
|
|
public void ToPrior()
|
{
|
//当前记录是第一条记录,不处理
|
if (_GridView.FocusedRowHandle == 0) return;
|
|
//当前记录
|
var R1 = _GridView.GetFocusedDataRow();
|
var sort1 = GetSortValue(R1[_SortFieldName]);
|
|
//取上一条记录
|
var R2 = _GridView.GetDataRow(_GridView.FocusedRowHandle - 1);
|
var sort2 = GetSortValue(R2[_SortFieldName]);
|
|
//交换序号
|
R1[_SortFieldName] = sort2;
|
R2[_SortFieldName] = sort1;
|
|
_GridView.GridControl.RefreshDataSource();
|
}
|
|
/// <summary>
|
/// 检测排序字段的值
|
/// </summary>
|
/// <param name="resetIfNullValue">True:若检测排序字段的值为空,自动重置排序ID, False:不排序</param>
|
/// <returns></returns>
|
private bool CheckSortValue(bool resetIfNullValue)
|
{
|
var hasNullValue = false;
|
foreach (DataRow R in DataSource.Rows)
|
if (R[_SortFieldName] == DBNull.Value //空值
|
|| R[_SortFieldName].ToStringEx().Trim() == "" //空值
|
|| Convert.ToDecimal(R[_SortFieldName].ToStringEx()
|
.Trim()) == 0) //等于0
|
{
|
hasNullValue = true;
|
break;
|
}
|
|
if (hasNullValue && resetIfNullValue) Reset();
|
|
return hasNullValue;
|
}
|
|
private decimal GetSortValue(object fieldValue)
|
{
|
if (fieldValue == DBNull.Value) return 0;
|
|
return Convert.ToDecimal(fieldValue);
|
}
|
}
|
}
|