GridView实现自定义按钮及中间插入记录排序功能
这命题有点长否则很难说明本文内容,这并不重要。下面详细讲解我想表达的内容。
先创建一个窗体并拖放一个GridControl控件,设置Column属性等。设UseEmbeddedNavigator=false
将GridControl.EmbeddedNavigator.Buttons内一些没用的按钮visible属性设为false.最终结果如下图:
图一,设计界面
图二, 设计自定义按钮
/// <summary>
/// 增加3个自定义按钮
/// </summary>
private void AddCustomButton()
{
gcDetail.BeginInit();
gcDetail.EmbeddedNavigator.Buttons.ImageList = this.imageList1;
ControlNavigatorButtons btns = gcDetail.EmbeddedNavigator.Buttons;
btns.CustomButtons.Clear();
NavigatorCustomButton btnDtlAdd = new NavigatorCustomButton((int)DetailButtons.Add,
"新增记录");
NavigatorCustomButton btnDtlInsert = new NavigatorCustomButton((int)DetailButtons.Insert,
"插入记录");
NavigatorCustomButton btnDtlDelete = new NavigatorCustomButton((int)DetailButtons.Delete,
"删除记录");
btns.CustomButtons.AddRange(new NavigatorCustomButton[] { btnDtlAdd, btnDtlInsert,
btnDtlDelete });
gcDetail.EndInit();
}
//原创文章,如转载请注明出处。by www.csframework.com C/S框架网
自定义按钮编号(ImageList图片编号,又用作自定义按钮编号
/// <summary>
/// 明细表Grid自定义按钮编号(ImageList图片编号,又用作自定义按钮编号,一箭双雕!)
/// </summary>
public class DetailButtons
{
public const int Add = 0;
public const int Insert = 1;
public const int Delete = 2;
}
图三,程序运行,在中间插入记录或Append记录
我们在开发过程中会遇到这样的问题:用户需要在某记录中间插入一条记录,报表内要显示同样的顺序。
做法有多种,最常用简单的处理方式是定义一个OrderField字段,用于保存排序数据。在界面中不显示
OrderField栏位,隐藏起来,用户那知道你干了些啥?
我的设计思路是: 假设新增第一条记录OrderField的值为1,Append一条为1.1, 依此类推,1.2,1.3,1.x.
是升序排列。如果要在中间插入记录则计算(n-1,n,n+1:n为当前记录)的值,算法如下:
/// 生成排序编号
/// </summary>
public class GenerateSortID
{
public readonly string DEF_FIRST_SORTING_PRIOR = "0.0";
public readonly string DEF_SORTING_SEPRATOR = ".";
public readonly string DEF_FIRST_SORTING = "1";
public readonly decimal DEF_STEP = (decimal)0.2; //步辐.
public readonly int DEF_MAX_SORTING_LENGTH = 20;
public GenerateSortID() { }
/// <summary>
/// 获取指定列的唯一数值.
/// </summary>
public ArrayList GetMRUFilters(GridView view, GridColumn col)
{
ArrayList list = new ArrayList();
try
{
for (int i = 0; i < view.RowCount; i++)
{
object o = view.GetRowCellValue(i, col);
if (!list.Contains(o) && !o.ToString().Equals(string.Empty)) list.Add(o);
}
list.Sort(); //默认为Ascedent
return list;
}
catch
{
return list;
}
}
/// <summary>
/// 获取最大的排序编号
/// </summary>
public int GetMaxSortingID(ArrayList sortingFilters)
{
try
{
sortingFilters.Sort();
string str = (string)sortingFilters[sortingFilters.Count - 1];
string[] arr = str.Split(Convert.ToChar(DEF_SORTING_SEPRATOR));
return Convert.ToInt16(arr[0]);
}
catch
{
return int.Parse(DEF_FIRST_SORTING);
}
}
/// <summary>
/// 生成一个新的排序编号
/// </summary>
/// <param name="currSortingID">当前行的Sort编号</param>
/// <param name="prevSortingID">前一行的Sort编号</param>
public string GetNewSortingID(string currSortingID, string prevSortingID)
{
try
{
if (prevSortingID == null) prevSortingID = DEF_FIRST_SORTING_PRIOR;
decimal prefix = decimal.Parse(prevSortingID);
decimal curr = decimal.Parse(currSortingID);
decimal newid = (curr - prefix) / 2 + prefix;
string ret = newid.ToString();
return ret.Replace("5", "4");
}
catch
{
return currSortingID;
}
}
/// <summary>
/// 生成排序字符串.
/// Insert方法生成规则,假设当前记录为n:
/// Append方法生成规则:生成的排序字符串为max(n)+1
/// </summary>
public string Generate(GridView view, GridColumn sortingColumn)
{
try
{
ArrayList list = GetMRUFilters(view, sortingColumn);
if (view.RowCount <= 0) return DEF_FIRST_SORTING; //设置默认排序ID
int pos = view.FocusedRowHandle;
int value = 0;
if (pos < 0) //没有当前记录. 以Append方式生成排序字符串
{
value = GetMaxSortingID(list);
return value.ToString() + DEF_SORTING_SEPRATOR;
}
else if (pos == view.RowCount - 1) // 视为Append.
{
string currID = view.GetRowCellValue(pos, sortingColumn).ToString();
decimal append = decimal.Parse(currID) + DEF_STEP;
return append.ToString();
}
else
{
object currobj = view.GetRowCellValue(pos, sortingColumn);
//Sorting最大长度为20. 如果生成的SortingID大於20.则取当前的SortingID
if (currobj.ToString().Length >= DEF_MAX_SORTING_LENGTH) return currobj.ToString();
object preobj = view.GetRowCellValue(pos - 1, sortingColumn);
if (Convert.ToString(preobj) == "") preobj = (object)0; //如果当前记录是第一条, 那麽上一条记录为0.
return GetNewSortingID(currobj.ToString(), preobj.ToString());
}
}
catch
{
return DEF_FIRST_SORTING;
}
}
}
//原创文章,如转载请注明出处。by www.csframework.com C/S框架网
跟据GridView的OrderField栏位计算的,这里可优化算法,直接计算DataTable的OrderField值.
计算(n-1,n,n+1:n为当前记录)的值.
计算出当前记录排序值,保存在OrderField字段,下面是新增一条记录的代码
/// <summary>
/// 创建一条明细记录。buttonIndex是Append或Insert的按钮编号
/// </summary>
/// <param name="buttonIndex"></param>
private void CreateOneDetail(int buttonIndex)
{
//因需要取OrderID,Append狀態下要將光標移到最後一行方可獲取正确OrderID
if (buttonIndex == DetailButtons.Add) gvDetail.MoveLast();
DataRow row = _dataSource.NewRow();
row["Qty"] = 0;//set a default value
if (gvDetail.RowCount == 0) buttonIndex = DetailButtons.Add;
string order = new GenerateSortID().Generate(gvDetail, colOrderField);
row["OrderField"] = order; //排序字段赋值
if (buttonIndex == DetailButtons.Add)
{
_dataSource.Rows.Add(row);
gcDetail.RefreshDataSource();
gvDetail.FocusedRowHandle = gvDetail.RowCount - 1;
}
else if (buttonIndex == DetailButtons.Insert)
{
_dataSource.Rows.InsertAt(row, gvDetail.FocusedRowHandle);
gvDetail.FocusedRowHandle = gvDetail.FocusedRowHandle - 1;
}
gvDetail.FocusedColumn = gvDetail.VisibleColumns[0];
}
//原创文章,如转载请注明出处。by www.csframework.com C/S框架网
最重要的是获取数据的sql语句:
select * from t_product order by OrderField
这样,保证用户输入的顺序与报表一致了!
开发环境: DevExpress 9.2x + VS2008