Delphi Listview leaves selection marks behind [duplicate] - delphi

I am using listview in vsreport virtual mode, have two columns and after I populate the list, select one row, and then select some other row there's an artifact left on a previously selected row, see image below. How to fix this?
and this is my code that gets the data from an array
procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem);
begin
Item.Caption := FloatToStr(Item.Index + 1);
Item.SubItems.Add(FloatToStr(a[Item.Index]));
end;
When I hover the mouse, the artifacts dissapear.
Thanks

Setting the listview's DoubleBuffered property to true solves the artifacts problem.

Related

Delphi: Bind a Chart with a DBGrid

I want to bind a Chart with a DBGrid.
Refer to the exhibit.
When I click in the DBGrid on number 3 (X-Axis), then the bar at position three should be highlighted(or a pointer to bar 3).
When I click on number 4 in the Grid then bar 4 is highlighted etc.
I'm using a TDBChart
Is there a way to do this?
Not knowing what the charting component is, cannot provide a working example, but the key which you are looking for is to use the AfterScroll event for the dataset in the grid. Since each row represents a different record, that event is fired when the grid selection moves to the row.
Edit: This doesn't highlight with a box, but does change the color of the value marks at the top of each bar. Hopefully this gets you on your way. MyQuery is what is feeding the datasource
var
savecolor : tcolor;
procedure MyForm.FormShow(Sender:TObject);
begin
...
SaveColor := dbchart1.series[0].marks.items[0].color;
...
end;
procedure MyForm.MyQueryBeforeScroll(DataSet : TDataSet);
begin
dbchart1.series[0].marks.items[MyQuery.recno-1].color := SaveColor;
end;
procedure MyForm.MyQueryAfterScroll(DataSet:TDataSet);
begin
dbchart1.series[0].marks.items[MyQuery.recno-1].color := clRed;
end;

Delphi, expand grouped by grid by default

I have this procedure for a grid in Delphi, and I need to add this property to expand all collapsed grouped by data in the grid.
procedure TProjectForm.dxDBGridEventDrawCell(
Sender: TcxCustomGridTableView; ACanvas: TcxCanvas;
AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean);
begin
inherited;
DrawHighlight(ACanvas);
TcxGridDbTableView.ViewData.Expand(True);
end;
I get the following error:
E2233 Property 'ViewData' inaccessible here
Help is appreciated please. And I also need to remove the collapsible button for the grouped data in this grid. Thank you
You can call cxGrid1DBTableView1.ViewData.Expand(True) without problems as long as you don't do in in a drawing event like the one in your q. However, you don't actually need to do this if you use the example below.
This works fine
procedure TDevexGroupingForm.FormCreate(Sender: TObject);
begin
cxGrid1DBTableView1.Columns[2].GroupIndex := 0; // group by the 3rd column
// NOTE: this step is only necessary if the table view has not been grouped at design-time
cxGrid1DBTableView1.DataController.Options := cxGrid1DBTableView1.DataController.Options
+ [dcoGroupsAlwaysExpanded]; // this hides the +/- buttons of the grouped nodes
cxGrid1DBTableView1.DataController.FocusedRowIndex := 0; // focuses the first group
end;
Note : This has been updated at #Nil's suggestion.
The first line, setting a column's GroupIndex is only necessary if the TableView has not already been grouped at design time.
Setting the FocusedRowIndex is optional, depending on how you want the TableView to display initially
So in fact the hiding of the +/- grouping buttons and the expansion of all the top-level group nodes can be achieved by the single step of setting the DataController Options property to include the dcoGroupsAlwaysExpanded option.
Btw Setting the DataController options to suppress the drawing of the expand/collapse buttons and is derived from the article https://www.devexpress.com/Support/Center/Question/Details/Q105527/how-do-i-hide-the-expand-button-on-a-grid

hyperlink field in DBGRID

I'm doing a small internal software to search branch lines in my company. In addition to the branch lines I also put an e-mail field in the database as shown below:
My intention is to click on the registered e-mail and the software via the ShellExecute open a window to send the e-mail. I'm using the option dgRowSelect as TRUE and because of that the OnCellClick event does not correctly identify which cell was clicked.
In my searches have not found any way to do this. Then I thought of using a TLabel within the field. I can use the onclick event in the TLabel and also change the cursor icon.
If TLabel is a good solution, how can I add a TLabel in DBGrid?
Or what would be another good solution?
I'm guessing that purpose of dgRowSelect=true is for highlighting whole selected row.
TLabel is not the way I would go - I would set dgRowSelect=false and paint selected row in OnDrawColumnCell or create my own fixed dbgrid.
There was a similar question:
how can i colour whole row in DBGrid with rowselect turned off?
Anyway if you want to use dgRowSelect=true and get valid info about clicked cell, here it is:
type THackDBGrid=class(TDBGrid);
procedure TForm1.dbgrd1CellClick(Column: TColumn);
var p:TPoint;
col:TGridCoord;
i: Integer;
grid:THackDBGrid;
begin
p := Mouse.CursorPos;
grid := THackDBGrid(Column.Grid);
p := grid.ScreenToClient(p);
col := grid.MouseCoord(p.X,p.Y);
i := grid.RawToDataColumn(col.X);
Label1.Caption := 'Column index: ' + IntToStr(i);
end;

Delphi XE2 listview artifacts

I am using listview in vsreport virtual mode, have two columns and after I populate the list, select one row, and then select some other row there's an artifact left on a previously selected row, see image below. How to fix this?
and this is my code that gets the data from an array
procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem);
begin
Item.Caption := FloatToStr(Item.Index + 1);
Item.SubItems.Add(FloatToStr(a[Item.Index]));
end;
When I hover the mouse, the artifacts dissapear.
Thanks
Setting the listview's DoubleBuffered property to true solves the artifacts problem.

TListBox Drag and Drop problems with MultiSelect enabled

I have a TListBox with multiselect and ExtendedSelect both set to true. I need to be able to drag multiple items in the list box to re-arrange them. My problem is what happens when the user clicks on an item that is already selected without holding down the CTRL or SHIFT key.
Case 1: DragMode is set to dmManual
The selection is cleared before the mouse down. This will not allow multiple items to be dragged.
Case 2: DragMode is set to dmAutomatic
The MouseDown event never fires. The selection is not cleared so dragging is OK, but the user cannot clear the selection by clicking on one of the selected items. This really causes a problem if all the items are selected or the next item the user wants to select was part of the current selection.
Note that this problem only happens if you assign something to the DragObject in the OnStartDrag procedure. I think the problem would go away if OnStartDrag would only start after the user moves the mouse. I have Mouse.DragImmediate := false set but I still get the StartDrag fired as soon as I click on an item in the list box.
I am using Delphi 7 for this project but I see the same behavior in Delphi 2007.
I have played with this for a while. And observe the same effects.
I would use Case2 and add a (Select All/Deselect All) button to the list. It even adds extra functionality and solves the most annoying part of the problem.
Use Case 2 and when the TListBox.OnMouseUp event fires check to see if multiple items are selected and were dragged. If multiple items are selected, but weren't dragged, then deselect all items apart from the clicked item.
I would use this method because Windows Explorer works this way.
Bit of a kludge but this works. DragMode on the ListBox is set to dmAutomatic.
procedure TForm1.ListBox1DragDrop(Sender, Source: TObject; X, Y: Integer);
var
iDropIdx, i: Integer;
pDropPoint: TPoint;
slSelected: TStrings;
begin
{Which item is being dropped onto?}
pDropPoint := Point(X, Y);
iDropIdx := ListBox1.ItemAtPos(pDropPoint, False);
slSelected := TStringList.Create;
try
{Copy the selected items to another string list}
for i := 0 to Pred(ListBox1.Items.Count) do
begin
if (ListBox1.Selected[i]) then
slSelected.Append(ListBox1.Items[i]);
end;
{Find the selected items in the listbox and swap them with the drop target}
for i := 0 to Pred(slSelected.Count) do
begin
ListBox1.Items.Exchange(ListBox1.Items.IndexOf(slSelected[i]), iDropIdx);
inc(iDropIdx);
end;
finally
slSelected.Free;
end;
end;
I'm not sure why this makes a difference but if I change the DragObject to be a TDragControlObjectEx (instead of a TDragObjectEx) I get the behavior I am looking for. Drag mode is set to Automatic.
I tried to look and see what this was affecting but I could not figure it out.

Resources