急求!! cxGrid中设置了GridMode=True,怎样再可以使用多选,遍历全部或者部分超出表格显示范围的数据???分数不够可另外加贴送分!!

时间:2022-12-16 16:22:28
设置了GridMode=True,遍历多选记录时,总是提示内存异常错误,大家帮帮忙呀!!!

14 个解决方案

#1


有这方面的高手吗,帮着解决一下,谢谢啦。

#2


不是不想帮你,是cxGrid没有用过。

#3


用过cxGrid的高手赶紧来指点一下呀。
即使不用GridMode也可以,只要是能提高速度又可以用多选功能就可以。我没有解决办法了。

#4


不懂,帮顶,接分。

#5


如果GridMode=False
那么打开数据集之后grid自身要遍历一遍数据
你把遍历的代码帖出来看看

#6


对于cxGrid5.0,做如下修改即可。可能还有针对其他问题的修改。

cxGridCustomTableView.pas
4568行改为:Result := TcxCustomGridRecord(FRecords[abs(Index)]);


cxDBData.pas
1867行:回车换行,然后增加:
begin
  if not DataSet.Active then Exit;

  ......
  ......
end;




2005-12-15:
cxDBData.pas 1908行 

procedure TcxDBDataProvider.MoveBy(ADistance: Integer);
begin
  if Assigned(DataSet) then
    DataSet.MoveBy(ADistance);
end;
改为:
procedure TcxDBDataProvider.MoveBy(ADistance: Integer);
begin
  if Assigned(DataSet) then
  begin
    if DataSet.State in [dsInsert, dsEdit] then
      DataSet.Cancel;
    DataSet.MoveBy(ADistance);
  end;
end;

cxGridCustomTableView.pas 8935行,回车,粘贴 DataController.Cancel;

#7


真的是高手!!!~
这样的话,对cxGrid的其他功能有没有影响呀~~

#8


TO hanlin2004(道德守望者):
用行数的话有些不明确呀,我的行数和你的行数好像不太一样。改完了我编译就出现错误了,都是内存地址错误。

#9


cxGrid1DBTableView1的GridMode为True,
把选中的记录中的一个字段添加到Memo1中。这样运行就会有错误了

procedure TForm1.Button1Click(Sender: TObject);
var
  iRowCount, i, n: Integer;
begin
  iRowCount := cxGrid1DBTableView1.Controller.SelectedRecordCount;
  showmessage(IntToStr(iRowCount));
  for i:=0 to iRowCount-1 do
  begin
    n := cxGrid1DBTableView1.Controller.SelectedRows[i].RecordIndex;
    inc(n);
    Memo1.Lines.Add(IntToStr(cxGrid1DBTableView1.Controller.SelectedRecords[i].Values[0]));
  end;
end;

#10


GridMode方式下处理有些不同
遍历选中的记录我是这么做的:
      for i:=0 to cxGridDBTableView2.DataController.RecordCount - 1 do
      begin
        if cxGridDBTableView2.DataController.IsRowSelected(i) then
        begin
          sessionid := vartostrdef(cxGridDBTableView2.DataController.GetValue(i, 0), '');
          ...
        end;
      end;

#11


我用的是cxGrid5.0

cxGridCustomTableView.pas
4568行
function TcxCustomGridTableViewData.GetInternalRecord(Index: Integer): TcxCustomGridRecord;
begin
  Result := TcxCustomGridRecord(FRecords[abs(Index)]);///////
end;


cxDBData.pas
1867行:
procedure TcxDBDataProvider.First;
var
  AReopened: Boolean;
begin
  FInFirst := True;
  try
    inherited First;
    if Assigned(DataSet) then
    begin
      if not DataSet.Active then Exit;///////
      with DataController do
      begin
      ....


2005-12-15:
cxDBData.pas 1908行 
procedure TcxDBDataProvider.MoveBy(ADistance: Integer);
begin
  if Assigned(DataSet) then
  begin
    if DataSet.State in [dsInsert, dsEdit] then/////
      DataSet.Cancel;/////
    DataSet.MoveBy(ADistance);
  end;
end;

cxGridCustomTableView.pas 8935行
function TcxCustomGridTableController.FocusNextRecord(AFocusedRecordIndex: Integer;
  AGoForward, AGoOnCycle, AGoIntoOutDetail: Boolean): Boolean;
var
  AGridView: TcxCustomGridTableView;
  APrevFocused, ACycleChanged: Boolean;
  APrevFocusedRecord, ANextRecord, AChildRecord: TcxCustomGridRecord;
  ANextRecordIndex: Integer;

  procedure CheckEditing;
  var
    AGridView: TcxCustomGridTableView;
  begin
    AGridView := GridView;
    //AGridView.BeginUpdate;   - commented because of dialog calling in OnBeforePost
    AGridView.AddListenerLink(@AGridView);
    try
      if DataController.IsEditing then
      begin
        EditingController.UpdateValue;
        DataController.Cancel;//////////////////
        if not (dceModified in DataController.EditState) then
        begin
        ...

#12


To:hanlin2004(道德守望者)
您的遍历方式查到的是这个窗口中的数据的。对超过了窗口记录范围外的数据就遍历不到了。
cxGridDBTableView2.DataController.RecordCount 显示的并不是数据集的全部记录数。

#13


===========================================================================

得到选中记录的值

1) View.DataController.DataModeController.GridMode = False时

  RecIdx := View.Controller.SelectedRecords[i].RecordIndex;
  ColIdx := View.DataController.GetItemByFieldName(AFieldName).Index;
  OutputVal := View.DataController.Values[RecIdx, ColIdx];

  //RecID := View.DataController.GetRecordId(RecIdx);
  //OutputVal := ADataSet.Lookup(View.DataController.KeyFieldNames, RecID, AFieldName);

2) View.DataController.DataModeController.GridMode = True时
  Bkm := View.DataController.GetSelectedBookmark(ASelectedRecordIndex);
  if ADataSet.BookmarkValid(TBookmark(Bkm)) then
  begin
    ADataSet.Bookmark := TBookmark(Bkm);
    OutputVal := ADataSet.FieldByName(AFieldName).Value;
  end;

  View.BeginUpdate;
  View.DataController.BeginLocate;
  try
    // make changes here…
  finally
    View.DataController.EndLocate;
    View.EndUpdate;
  end;

=============================================================

#14


太好了。非常感谢,终于解决掉了。cxGrid的功能还是很强大的,就是现在外面的一些介绍太少了,相应的帮助和文档也不好找到。能够读懂它真的是不容易呀。、

再次感谢大家

#1


有这方面的高手吗,帮着解决一下,谢谢啦。

#2


不是不想帮你,是cxGrid没有用过。

#3


用过cxGrid的高手赶紧来指点一下呀。
即使不用GridMode也可以,只要是能提高速度又可以用多选功能就可以。我没有解决办法了。

#4


不懂,帮顶,接分。

#5


如果GridMode=False
那么打开数据集之后grid自身要遍历一遍数据
你把遍历的代码帖出来看看

#6


对于cxGrid5.0,做如下修改即可。可能还有针对其他问题的修改。

cxGridCustomTableView.pas
4568行改为:Result := TcxCustomGridRecord(FRecords[abs(Index)]);


cxDBData.pas
1867行:回车换行,然后增加:
begin
  if not DataSet.Active then Exit;

  ......
  ......
end;




2005-12-15:
cxDBData.pas 1908行 

procedure TcxDBDataProvider.MoveBy(ADistance: Integer);
begin
  if Assigned(DataSet) then
    DataSet.MoveBy(ADistance);
end;
改为:
procedure TcxDBDataProvider.MoveBy(ADistance: Integer);
begin
  if Assigned(DataSet) then
  begin
    if DataSet.State in [dsInsert, dsEdit] then
      DataSet.Cancel;
    DataSet.MoveBy(ADistance);
  end;
end;

cxGridCustomTableView.pas 8935行,回车,粘贴 DataController.Cancel;

#7


真的是高手!!!~
这样的话,对cxGrid的其他功能有没有影响呀~~

#8


TO hanlin2004(道德守望者):
用行数的话有些不明确呀,我的行数和你的行数好像不太一样。改完了我编译就出现错误了,都是内存地址错误。

#9


cxGrid1DBTableView1的GridMode为True,
把选中的记录中的一个字段添加到Memo1中。这样运行就会有错误了

procedure TForm1.Button1Click(Sender: TObject);
var
  iRowCount, i, n: Integer;
begin
  iRowCount := cxGrid1DBTableView1.Controller.SelectedRecordCount;
  showmessage(IntToStr(iRowCount));
  for i:=0 to iRowCount-1 do
  begin
    n := cxGrid1DBTableView1.Controller.SelectedRows[i].RecordIndex;
    inc(n);
    Memo1.Lines.Add(IntToStr(cxGrid1DBTableView1.Controller.SelectedRecords[i].Values[0]));
  end;
end;

#10


GridMode方式下处理有些不同
遍历选中的记录我是这么做的:
      for i:=0 to cxGridDBTableView2.DataController.RecordCount - 1 do
      begin
        if cxGridDBTableView2.DataController.IsRowSelected(i) then
        begin
          sessionid := vartostrdef(cxGridDBTableView2.DataController.GetValue(i, 0), '');
          ...
        end;
      end;

#11


我用的是cxGrid5.0

cxGridCustomTableView.pas
4568行
function TcxCustomGridTableViewData.GetInternalRecord(Index: Integer): TcxCustomGridRecord;
begin
  Result := TcxCustomGridRecord(FRecords[abs(Index)]);///////
end;


cxDBData.pas
1867行:
procedure TcxDBDataProvider.First;
var
  AReopened: Boolean;
begin
  FInFirst := True;
  try
    inherited First;
    if Assigned(DataSet) then
    begin
      if not DataSet.Active then Exit;///////
      with DataController do
      begin
      ....


2005-12-15:
cxDBData.pas 1908行 
procedure TcxDBDataProvider.MoveBy(ADistance: Integer);
begin
  if Assigned(DataSet) then
  begin
    if DataSet.State in [dsInsert, dsEdit] then/////
      DataSet.Cancel;/////
    DataSet.MoveBy(ADistance);
  end;
end;

cxGridCustomTableView.pas 8935行
function TcxCustomGridTableController.FocusNextRecord(AFocusedRecordIndex: Integer;
  AGoForward, AGoOnCycle, AGoIntoOutDetail: Boolean): Boolean;
var
  AGridView: TcxCustomGridTableView;
  APrevFocused, ACycleChanged: Boolean;
  APrevFocusedRecord, ANextRecord, AChildRecord: TcxCustomGridRecord;
  ANextRecordIndex: Integer;

  procedure CheckEditing;
  var
    AGridView: TcxCustomGridTableView;
  begin
    AGridView := GridView;
    //AGridView.BeginUpdate;   - commented because of dialog calling in OnBeforePost
    AGridView.AddListenerLink(@AGridView);
    try
      if DataController.IsEditing then
      begin
        EditingController.UpdateValue;
        DataController.Cancel;//////////////////
        if not (dceModified in DataController.EditState) then
        begin
        ...

#12


To:hanlin2004(道德守望者)
您的遍历方式查到的是这个窗口中的数据的。对超过了窗口记录范围外的数据就遍历不到了。
cxGridDBTableView2.DataController.RecordCount 显示的并不是数据集的全部记录数。

#13


===========================================================================

得到选中记录的值

1) View.DataController.DataModeController.GridMode = False时

  RecIdx := View.Controller.SelectedRecords[i].RecordIndex;
  ColIdx := View.DataController.GetItemByFieldName(AFieldName).Index;
  OutputVal := View.DataController.Values[RecIdx, ColIdx];

  //RecID := View.DataController.GetRecordId(RecIdx);
  //OutputVal := ADataSet.Lookup(View.DataController.KeyFieldNames, RecID, AFieldName);

2) View.DataController.DataModeController.GridMode = True时
  Bkm := View.DataController.GetSelectedBookmark(ASelectedRecordIndex);
  if ADataSet.BookmarkValid(TBookmark(Bkm)) then
  begin
    ADataSet.Bookmark := TBookmark(Bkm);
    OutputVal := ADataSet.FieldByName(AFieldName).Value;
  end;

  View.BeginUpdate;
  View.DataController.BeginLocate;
  try
    // make changes here…
  finally
    View.DataController.EndLocate;
    View.EndUpdate;
  end;

=============================================================

#14


太好了。非常感谢,终于解决掉了。cxGrid的功能还是很强大的,就是现在外面的一些介绍太少了,相应的帮助和文档也不好找到。能够读懂它真的是不容易呀。、

再次感谢大家