[Delphi] Checkbox in subitem van ListView

Pagina: 1
Acties:
  • 310 views sinds 30-01-2008
  • Reageer

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Is het mogelijk om een ListView een checkbox te stoppen (read-only), maar dan niet in de eerste kolom. Ik verwacht dat het met CustomDrawSubItem moet, maar heb totaal geen idee.

Wel is het me gelukt met een DBGrid:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
procedure TFacturenForm.GridFacturenDrawColumnCell(Sender: TObject;
  const Rect: TRect; DataCol: Integer; Column: TColumn;
  State: TGridDrawState);
var
  Style: UINT;
begin
  inherited;
  if Column.Title.Caption = 'Incasso' then begin
    Style := DFCS_BUTTONCHECK;
    if MainDataModule.QueryFactuurINCASSO.AsBoolean = True then Style := Style or DFCS_CHECKED;
    DrawFrameControl(GridFacturen.Canvas.Handle, Rect, DFC_BUTTON, Style);
  end else GridFacturen.DefaultDrawColumnCell(Rect, DataCol, Column, State);
end;

Dan krijg je dit:
Afbeeldingslocatie: http://httpd.chello.nl/~j.vos6/tweakers/listcheckbox.jpg

Overigens is het wel read-only, maar dat maakt voor die CheckBox's niet uit.

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • whoami
  • Registratie: December 2000
  • Nu online
Ik heb hier een beetje zitten Builderen.
Ik krijg wel een checkbox in de ListView, maar niet op de goede plaats. Het probleem zit hem in de tagRect parameter van de DrawFrameControl functie.
Ik zou nl een pointer moeten hebben naar de Rectangle van dat subitem. Ik weet niet hoe ik die moet verkrijgen.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void __fastcall TForm1::ListView1CustomDrawSubItem(TCustomListView *Sender,
    TListItem *Item, int SubItem, TCustomDrawState State,
    bool &DefaultDraw)
{
  if (SubItem == 2) // het 2de subitem moet checkbox zijn (de 3de kolom dus)
  {
    DefaultDraw = false;

    TRect RC;
    RC = Item->DisplayRect(drBounds);

    DrawFrameControl (ListView1->Canvas->Handle, &RC,
                DFC_BUTTON, DFCS_BUTTONCHECK);
    if (Item->SubItems->Strings[SubItem-1] == "1")
    {
    State << cdsChecked;
    }
    else
    {
    State >> cdsChecked;
    }
  }

}

Misschien dat je hiermee een beetje op weg raakt...

https://fgheysels.github.io/


  • mulder
  • Registratie: Augustus 2001
  • Nu online

mulder

ik spuug op het trottoir

BTW, waarom een checkbox als deze toch read-only is? Lijkt mij overbodig, word pas interessant als deze juist niet read-only is. Kun je er geen event aanplakken?

oogjes open, snaveltjes dicht


  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Op zaterdag 15 december 2001 18:03 schreef El_Mundo het volgende:
BTW, waarom een checkbox als deze toch read-only is? Lijkt mij overbodig, word pas interessant als deze juist niet read-only is. Kun je er geen event aanplakken?
Het is alleen voor de duidelijkheid. True/False/Ja/Nee vind ik niet zo netjes staan, een checkbox met wel of niet een vinkje staat toch net even netter.

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Bedankt voor de oplossing, zal er zo even mee aan de gang.

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • whoami
  • Registratie: December 2000
  • Nu online
Op zaterdag 15 december 2001 18:48 schreef jelmervos het volgende:
Bedankt voor de oplossing, zal er zo even mee aan de gang.
Nuja, oplossing. Je zult zelf wel zien dat het nog niet echt dat is hoor. Heb er ook maar een kwartiertje op gezocht.

https://fgheysels.github.io/


  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Op zaterdag 15 december 2001 18:49 schreef whoami het volgende:

[..]

Nuja, oplossing. Je zult zelf wel zien dat het nog niet echt dat is hoor. Heb er ook maar een kwartiertje op gezocht.
Oke, iig bedankt. Meestal helpt het ook wel als iemand me op gang helpt.
Natuurlijk heb ik voor het plaatsen van dit topic ook even gezocht met Google (vooral groups), maar kwam weinig discussies tegen met zelfde vraag. Dat was wel anders toen ik in die DBGrid van die checkbox's wilde.

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • whoami
  • Registratie: December 2000
  • Nu online
Als je gevonden hebt hoe het helemaal moet, wil je het dan even posten?

https://fgheysels.github.io/


  • JapJap
  • Registratie: Maart 2001
  • Laatst online: 07-01 11:02
Heb ooit ook zoiet gemaakt, misschien heb je er wat aan.

OnDrawColumnCell:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
procedure X.OnDrawColumnCell(Sender: TObject;
  const Rect: TRect; DataCol: Integer; Column: TColumn;
  State: TGridDrawState);
var
  Bitmap: TBitmap;
begin
  if (DataCol = 3) and (xxx.AsBoolean) then
  with (Sender as TDBGrid) do begin
    Bitmap := TBitmap.Create;
    try
    ilImageList.GetBitmap(1, Bitmap);
    if gdSelected in State then //Select copymode
      Canvas.CopyMode := cmMergePaint
    else
      Canvas.CopyMode := cmMergeCopy;
    Canvas.CopyRect(Rect, Bitmap.Canvas, Bitmap.Canvas.ClipRect);
    finally
    Bitmap.Free;
    end;
  end;
end;

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Maar dat is voor een DBGrid, dat heb ik dus ook al. Ik zoek hetzelfde voor een ListView.

"The shell stopped unexpectedly and Explorer.exe was restarted."


Verwijderd

whoami heeft je al aardig op weg geholpen met 't OnCustomDrawSubItem (en OnAdvancedCustomDrawSubItem) event van de ListView. Maar idd, simpel is 't niet...

Als 't wat mag kosten, kijk dan 's naar de QuantumTreeList suite van DevExpress.
Uit je screenshot maak ik op dat je niet voor jezelf bezig bent, maar voor een klant. Tijd is dan geld, en de jongens van DevExpress kunnen je dan een hoop tijd besparen (ook hun QuantumGrid is een aanradertje!).

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Dat ziet er zeker goed uit, maar is helaas niet gratis, en dan weet ik niet of ik het zomaar kan gebruiken. Daar heb ik weinig over te zeggen.


Overigens heb ik die checkbox's nu wel staan, maar die worden hopeloos verkeerd geplaatst.

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Nouja, ik zet er eerst wel gewoon "ja" en "nee" in. :)

"The shell stopped unexpectedly and Explorer.exe was restarted."


Verwijderd

Of je tekent 't vinkje zelf (ook wel zo mooi bij read only items):
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
procedure DrawCheckMark(ACanvas: TCanvas; ARect: TRect);
var
  XOffset, YOffset: integer;
begin
  with ACanvas do begin
    XOffset := ARect.Left + ((ARect.Right - ARect.Left) div 2) - 7;
    YOffset := ARect.Top + ((ARect.Bottom - ARect.Top) div 2) - 7;
    FillRect(ARect);
    Pen.Color := Font.Color;
    Brush.Style := bsSolid;
    Brush.Color := Font.Color;
    Polygon([Point(XOffset +  4, YOffset +  6),
         Point(XOffset +  4, YOffset +  8),
         Point(XOffset +  6, YOffset + 10),
         Point(XOffset + 10, YOffset +  6),
         Point(XOffset + 10, YOffset +  4),
         Point(XOffset +  6, YOffset +  8)]);
  end;
end;

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Kan ook, hoe pas ik dat precies toe in een ListView?

"The shell stopped unexpectedly and Explorer.exe was restarted."


Verwijderd

Weer in 't OnCustomDrawSubItem event.
ACanvas is 't canvas van je ListView, en ARect is dan Item.DisplayRect(drBounds).

Enne... Niet getest bij een ListView, maar 't werkt prima in een DrawGrid, een TreeView en een DBGrid. Zal dus wel gaan werken, denk ik zo... :)

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Ik heb dit gedaan bij CustomDrawSubItem, maar geeft een heel vreemd resultaat. De vinkjes komen op een verkeerde positie en de rest van de lijn wordt niet goed getekend. Bij het heen en weer schuiven van een column ziet het er nog vreemder uit.
code:
1
2
3
4
  if SubItem = 3 then begin
    DefaultDraw := False;
    DrawCheckMark(Sender.Canvas, Item.DisplayRect(drBounds));
  end else DefaultDraw := True;

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • whoami
  • Registratie: December 2000
  • Nu online
Op zondag 16 december 2001 17:23 schreef jelmervos het volgende:
Ik heb dit gedaan bij CustomDrawSubItem, maar geeft een heel vreemd resultaat. De vinkjes komen op een verkeerde positie en de rest van de lijn wordt niet goed getekend. Bij het heen en weer schuiven van een column ziet het er nog vreemder uit.
code:
1
2
3
4
  if SubItem = 3 then begin
    DefaultDraw := False;
    DrawCheckMark(Sender.Canvas, Item.DisplayRect(drBounds));
  end else DefaultDraw := True;
Ja, dit is een beetje hetzelfde probleem dat ik heb tegengekomen met het vinden van een oplossing van uw probleem.
Het probleem ligt hem bij de juiste positie waar die checkbox/vinkje moet komen. Je kan wel toegang krijgen tot de Canvas property of de Rect property van het TListItem. Maar die property van het juiste SubItem uitlezen kan niet. Dat zal ook niet zo makkelijk zijn, je kan de kolommen nl vergroten en verkleinen dus kan die waarde ook voortdurend wijzigen.

Misschien maar even bij een TDBGrid of een TGrid? Waarom wil je eigenlijk perse een TListView gebruiken?

https://fgheysels.github.io/


Verwijderd

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
procedure TForm1.ListView1CustomDrawSubItem(Sender: TCustomListView;
  Item: TListItem; SubItem: Integer; State: TCustomDrawState;
  var DefaultDraw: Boolean);
var
  R: TRect;
  i: integer;
begin
  if SubItem = 3 then begin
    R := Item.DisplayRect(drLabel);
    for i := 0 to SubItem-1 do
    R.Left := R.Left + Sender.Column[i].Width;
    R.Right := R.Left + Sender.Column[SubItem].Width;
    DefaultDraw := False;
    DrawCheckMark(Sender.Canvas, R);
  end else
    DefaultDraw := True;
end;

Vreemd ding, die ListView...
In vsReport style moet je blijkbaar zelf 't Rect van het desbetreffende subitem bepalen. Nou ja, weten we dat ook weer. :)

  • whoami
  • Registratie: December 2000
  • Nu online
Op maandag 17 december 2001 02:06 schreef Afterlife het volgende:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
procedure TForm1.ListView1CustomDrawSubItem(Sender: TCustomListView;
  Item: TListItem; SubItem: Integer; State: TCustomDrawState;
  var DefaultDraw: Boolean);
var
  R: TRect;
  i: integer;
begin
  if SubItem = 3 then begin
    R := Item.DisplayRect(drLabel);
    for i := 0 to SubItem-1 do
    R.Left := R.Left + Sender.Column[i].Width;
    R.Right := R.Left + Sender.Column[SubItem].Width;
    DefaultDraw := False;
    DrawCheckMark(Sender.Canvas, R);
  end else
    DefaultDraw := True;
end;

Vreemd ding, die ListView...
In vsReport style moet je blijkbaar zelf 't Rect van het desbetreffende subitem bepalen. Nou ja, weten we dat ook weer. :)
Met dit zou het zo wel moeten lukken denk ik. Wordt die OnCustomDrawSubItem event handler ook gefired bij het resizen?
* whoami denkt het wel maar is te lui om het te gaan testen.

https://fgheysels.github.io/


Verwijderd

Op maandag 17 december 2001 16:57 schreef whoami het volgende:
Wordt die OnCustomDrawSubItem event handler ook gefired bij het resizen?
* whoami denkt het wel maar is te lui om het te gaan testen.
Bij 't resizen van een kolom wordt 'ie alleen aangeroepen aan 't begin, en helaas niet wanneer je je resize actie beeindigt.
Maar daar mag 'ie lekker zelf een oplossing voor verzinnen. :)
Pagina: 1