Hello,
I have a rveTable in a TDBRichViewEdit (vers.1.9.18.1) with
- rveTable.Cells[r,c].BestWidth := 200
- rveTable.Cells[r,c].BestHeight:= -(100 div rveTable.Rows[r].Count);
cells-content is intToStr(r)+' * '+intToStr(c)
Now I want to make all
- Cells higher
- and give them a new content ('*')
All ok.
But when I select another record and go back to the changing record,
new content is vanished (old Content is to see).
But when I click in the memo (after clicking Button1Click) and write a text, new content will stay after scrolling through table.
Jürgen
procedure TForm1.Button1Click(Sender: TObject);
var r,c, ItemNo, Offs: Integer;
begin
if not (memo.GetCurrentItemEx(TRVTableItemInfo, rve, TCustomRVItemInfo(rveTable))) then begin
ShowMessage('Tabelle hat nicht den Focus.');
exit;
end;
// ? rveTable.OnCellEditing := OnCellEditing; <------ ?
for r := 0 to rveTable.Rows.Count-1 do
for c := 0 to rveTable.Rows[r].Count-1 do begin
rveTable.Cells[r,c].BestWidth := 25;
rveTable.Cells[r,c].BestHeight:= 25;
rveTable.Cells[r,c].clear; // <--------- ? look at next line
rveTable.Cells[r,c].AddNL('*',0,0); <--------- I overwrite old content
end;
memo.format;
end;
What's to do ?
Changing rveTable.cells content
-
- Site Admin
- Posts: 17602
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
BestHeight does not support negative values, they will be ignored. Only BestWidth treats them as %.- rveTable.Cells[r,c].BestWidth := 200
- rveTable.Cells[r,c].BestHeight:= -(100 div rveTable.Rows[r].Count);
By the way, rveTable.Rows[r].Count is a number of columns, not rows.
As for the question. The problem occurs because you use non-editing methods, they do not inform table that the document was modified, so changes are not saved.
Add the following:
1)
if not memo.CanChange then exit;
before making modifications
2) memo.Change
after.
Also, you need to call memo.ClearUndo, because using non-editing operations damages undo and redo buffers.
Also, check if Cells[r,c]<>nil, otherwise your application will crash if the table has merged cells.
But if you need to implement a editing operation, which can be undone/redone by the user, you need to use another approach: only editing-style methods must be used (no Clear, no AddNL, no direct assignment to BestWidth/BestHeight!)
Code: Select all
if not (memo.GetCurrentItemEx(TRVTableItemInfo, rve, TCustomRVItemInfo(rveTable))) then begin
ShowMessage('Tabelle hat nicht den Focus.');
exit;
end;
if not memo.CanChange then
exit;
ItemNo := rveTable.GetMyItemNo;
rve.BeginUndoGroup(rvutModifyItem);
rve.SetUndoGroupMode(True);
rve.BeginItemModify(ItemNo, Data);
for r := 0 to rveTable.Rows.Count-1 do
for c := 0 to rveTable.Rows[r].Count-1 do
if rveTable.Cells[r,c]<>nil then begin
rveTable.SetCellBestWidth(25, r, c);
rveTable.SetCellBestHeight(25, r, c);
end;
rve.EndItemModify(ItemNo, Data);
rve.SetUndoGroupMode(False);
rve.Change;
for r := 0 to rveTable.Rows.Count-1 do
for c := 0 to rveTable.Rows[r].Count-1 do
if rveTable.Cells[r,c]<>nil then begin
rveTable.EditCell(r,c);
rve.TopLevelEditor.SelectAll; // the cell is edited, so rve.TopLevelEditor is a cell inplace editor
rve.InsertText('*');
end;
Thank you, Sergey
Nice that you comment your code.
The 2. code
//memo.color:=clBtnFace;
for r := 0 to rveTable.Rows.Count-1 do
for c := 0 to rveTable.Rows[r].Count-1 do
if rveTable.Cells[r,c]<>nil then begin
rveTable.EditCell(r,c);
rve.TopLevelEditor.SelectAll; // the cell is edited, so rve.TopLevelEditor is a cell inplace editor
rve.InsertText('*');
end;
//memo.color:=clWhite; //crHourGlass + crDefault doesn't go
is very slow.
Because .crHourGlass and .crDefault doesn't go I change memo.color. Now user know if changing is ready
Nice that you comment your code.
The 2. code
//memo.color:=clBtnFace;
for r := 0 to rveTable.Rows.Count-1 do
for c := 0 to rveTable.Rows[r].Count-1 do
if rveTable.Cells[r,c]<>nil then begin
rveTable.EditCell(r,c);
rve.TopLevelEditor.SelectAll; // the cell is edited, so rve.TopLevelEditor is a cell inplace editor
rve.InsertText('*');
end;
//memo.color:=clWhite; //crHourGlass + crDefault doesn't go
is very slow.
Because .crHourGlass and .crDefault doesn't go I change memo.color. Now user know if changing is ready
-
- Site Admin
- Posts: 17602
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
Please add DisableUpdate and EnableUpdate to do the SendMessage. This would allow for 'stacking' disabled updates.
Ergo:
DisableUpdates:
- Check if a disbaled-counter equals zero. If it does, send the message to disable actual updates.
- Increase a counter
EnableUpdates:
- Decrease the counter if it is > 0, the if it reaches 0, send the message to enable redrawing and call Invalidate;
Ergo:
DisableUpdates:
- Check if a disbaled-counter equals zero. If it does, send the message to disable actual updates.
- Increase a counter
EnableUpdates:
- Decrease the counter if it is > 0, the if it reaches 0, send the message to enable redrawing and call Invalidate;
-
- Site Admin
- Posts: 17602
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
It would be too complex to implement. I mean, disabling the update of internal data representing formatting. Redrawing does not occur usually, because Invalidate does not repaint the window itself. This case is an exception, because it involves creating of inplace table editors.
And I think that this case is atypical. It's rarely required to make massive changes in the document as an editing command (that can be undone/redone). There is a set of non-editing methods for fast document generation and modification.
And I think that this case is atypical. It's rarely required to make massive changes in the document as an editing command (that can be undone/redone). There is a set of non-editing methods for fast document generation and modification.
Not too complicated:
I understand this may be 'too complicated to add', but I would be happy to use them as helper methods. Nice to have, I mean.
Code: Select all
TCustomRichView = class(TRVScroller)
private
{ Private declarations }
FUpdatesLock: Integer;
FCursor: TCursor;
...
public
procedure DisableUpdates;
procedure EnableUpdates;
...
end;
...
implementation
...
procedure TCustomRichView.DisableUpdates;
begin
if (FUpdatesLock = 0) and HandleAllocated then
SendMessage(Handle, WM_SETREDRAW, 0, 0);
Inc(FUpdatesLock);
end;
procedure TCustomRichView.EnableUpdates;
begin
Dec(FUpdatesLock);
if FUpdatesLock > 0 then Exit;
if HandleAllocated then
begin
SendMessage(Handle, WM_SETREDRAW, 1, 0);
Invalidate;
end;
FUpdatesLock := 0;
end;
...