You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用C++Builder访问TIWDBGrid列时触发“参数越界”错误的解决办法

问题描述

参考Delphi示例尝试用C++Builder访问TIWDBGrid的列时,触发「Argument out of range(参数越界)」错误,相关代码如下:

__fastcall TForm1::TForm1(TComponent* Owner) : TFrame(Owner)
{//
 TRESTClient *REST1Client = new TRESTClient(this);
 TRESTRequest *REST1Request = new TRESTRequest(this);
 TRESTResponse *REST1Response = new TRESTResponse(this);
 TClientDataSet *ClientDataSet1 = new TClientDataSet(this);
 TRESTResponseDataSetAdapter *REST1ResponseDataSetAdapter = new TRESTResponseDataSetAdapter(this);

 TDataSource *DataSource1 = new TDataSource(this);
 DataSource1->DataSet = ClientDataSet1;
 IWDBGrid1->DataSource = DataSource1;

 ClientDataSet1->AfterOpen = &ClientDataSet1AfterOpen;

 REST1Client->BaseURL = "my.URL.php";
 REST1Request->AddParameter("IdField", "IdValue");
 REST1Request->Client = REST1Client;
 REST1Request->Response = REST1Response;
 REST1Response->ContentType = "application/json";
 REST1ResponseDataSetAdapter->Dataset = ClientDataSet1;
 REST1ResponseDataSetAdapter->Response = REST1Response;
 REST1ResponseDataSetAdapter->Active = true;
 REST1Request->Execute();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ClientDataSet1AfterOpen(TDataSet *DataSet)
{//
 static_cast<TIWDBGridColumn*>(IWDBGrid1->Columns->Items[0])->Width = (IWDBGrid1->Width/20) * 02; // => Argument out of range
 static_cast<TIWDBGridColumn*>(IWDBGrid1->Columns->Items[1])->Width = (IWDBGrid1->Width/20) * 02;
 static_cast<TIWDBGridColumn*>(IWDBGrid1->Columns->Items[2])->Width = (IWDBGrid1->Width/20) * 13;
 static_cast<TIWDBGridColumn*>(IWDBGrid1->Columns->Items[3])->Width = (IWDBGrid1->Width/20) * 03;

 static_cast<TIWDBGridColumn*>(IWDBGrid1->Columns->Items[0])->Title->Text = "AFirstTitle";
 static_cast<TIWDBGridColumn*>(IWDBGrid1->Columns->Items[1])->Title->Text = "ASecondTitle";
 static_cast<TIWDBGridColumn*>(IWDBGrid1->Columns->Items[2])->Title->Text = "AThirdTitle";
 static_cast<TIWDBGridColumn*>(IWDBGrid1->Columns->Items[3])->Title->Text = "AFourthTitle";
 }
//---------------------------------------------------------------------------
void __fastcall TForm1::IWDBGrid1Render(TObject *Sender)
{//
 // static_cast<TIWDBGridColumn*>(IWDBGrid1->Columns->Items[0])->Width = (IWDBGrid1->Width/20) * 02; // => Argument out of range
}
//---------------------------------------------------------------------------
void __fastcall TForm1::IWFrameRegionRender(TObject *Sender)
{//
 // static_cast<TIWDBGridColumn*>(IWDBGrid1->Columns->Items[0])->Width = (IWDBGrid1->Width/20) * 02; // => Argument out of range
}
//---------------------------------------------------------------------------
解决方案

错误核心原因是TIWDBGrid的Columns集合在DataSet打开后并未自动创建对应列,直接通过索引访问会触发越界。以下是几种可行解决方式:

方法一:手动创建列并绑定字段

在DataSet打开前,手动为IWDBGrid创建对应数量的列,并绑定到ClientDataSet的字段:

__fastcall TForm1::TForm1(TComponent* Owner) : TFrame(Owner)
{
    // ... 保留原有初始化代码 ...

    // 提前创建4列(根据实际返回字段数量调整)
    for (int i = 0; i < 4; i++) {
        TIWDBGridColumn* Col = new TIWDBGridColumn(IWDBGrid1);
        // 绑定到ClientDataSet对应字段
        Col->FieldName = ClientDataSet1->Fields->Fields[i]->FieldName;
        IWDBGrid1->Columns->Add(Col);
    }

    ClientDataSet1->AfterOpen = &ClientDataSet1AfterOpen;

    // ... 保留后续REST请求代码 ...
}

方法二:开启自动创建列属性

检查TIWDBGrid的AutoCreateColumns属性,默认可能为false,可在设计时或代码中开启:

IWDBGrid1->AutoCreateColumns = true;

开启后,DataSet打开时IWDBGrid会自动根据字段生成对应列,此时访问Columns索引不会越界。

方法三:在Grid渲染事件中处理列属性

若上述方法不生效,可在IWDBGrid1Render事件中处理列属性,此时Grid已完成列创建:

void __fastcall TForm1::IWDBGrid1Render(TObject *Sender)
{
    // 先判断列数量是否足够,避免越界
    if (IWDBGrid1->Columns->Count >= 4) {
        static_cast<TIWDBGridColumn*>(IWDBGrid1->Columns->Items[0])->Width = (IWDBGrid1->Width/20)*2;
        static_cast<TIWDBGridColumn*>(IWDBGrid1->Columns->Items[1])->Width = (IWDBGrid1->Width/20)*2;
        static_cast<TIWDBGridColumn*>(IWDBGrid1->Columns->Items[2])->Width = (IWDBGrid1->Width/20)*13;
        static_cast<TIWDBGridColumn*>(IWDBGrid1->Columns->Items[3])->Width = (IWDBGrid1->Width/20)*3;

        static_cast<TIWDBGridColumn*>(IWDBGrid1->Columns->Items[0])->Title->Text = "AFirstTitle";
        static_cast<TIWDBGridColumn*>(IWDBGrid1->Columns->Items[1])->Title->Text = "ASecondTitle";
        static_cast<TIWDBGridColumn*>(IWDBGrid1->Columns->Items[2])->Title->Text = "AThirdTitle";
        static_cast<TIWDBGridColumn*>(IWDBGrid1->Columns->Items[3])->Title->Text = "AFourthTitle";
    }
}

额外注意事项

  • 确认ClientDataSet实际返回字段数量,可在ClientDataSet1AfterOpen中打印ClientDataSet1->FieldCount验证,避免字段数量不足导致越界。
  • 避免在构造函数中直接访问Grid列,此时Grid可能未完成初始化,优先使用AfterOpen或Render事件。

内容的提问来源于stack exchange,提问作者ibouka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 08:31:04