2010-04-20 3 views
4

Как создать список (или подобное) с помощью кнопки на каждой строке? При необходимости кнопка должна иметь различный текст/цвет на каждой строке.Delphi - ListView или аналогичный с кнопкой рисования владельца

Я уверен, что Virtual Treeview идеально подходит для этого, но я немного потерял его.

Благодаря

-Brad

ответ

4

С virtualtreeview ...... добавить vstButton ваших целей и выбрать Virtualtreeview в инспекторе объектов и задать следующие события для дерева:

procedure TForm1.VSTCreateEditor(Sender: TBaseVirtualTree; Node: PVirtualNode; 
    Column: TColumnIndex; out EditLink: IVTEditLink); 
begin 
    EditLink:=TStringEditLink.Create; 
end; 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    VST.NodeDataSize := SizeOf(TTreeData); 
    AddRandomNodesToTree(Vst); 
end; 

procedure TForm1.VSTFreeNode(Sender: TBaseVirtualTree; 
    Node: PVirtualNode); 
var 
Data: PTreeData; 
begin 
Data:=VST.GetNodeData(Node); 
if Assigned(Data) then begin 
    Data^.Column0 := ''; 
    Data^.Column1 := ''; 
    Data^.Column2 := ''; 
end; 
end; 

procedure TForm1.VSTGetText(Sender: TBaseVirtualTree; 
    Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; 
    var CellText: string); 
var 
    Data: PTreeData; 
begin 
    Data := VST.GetNodeData(Node); 
    case Column of 
    0: CellText := Data^.Column0; 
    1: CellText := Data^.Column1; 
    2: CellText := Data^.Column2; 
    end; 
end; 

procedure TForm1.VSTNewText(Sender: TBaseVirtualTree; Node: PVirtualNode; 
    Column: TColumnIndex; NewText: string); 
Var 
    Data: PTreeData; 
begin 
    Data := VST.GetNodeData(Node); 
    Case Column of 
    0: Data^.Column0:= NewText; 
    1: Data^.Column1:= NewText; 
    2: Data^.Column2:= NewText; 
    End; 
end; 

procedure TForm1.VSTPaintText(Sender: TBaseVirtualTree; 
    const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; 
    TextType: TVSTTextType); 
Var 
Data: PTreeData; 
begin 
    if Odd(Node.Index) then 
    TargetCanvas.Font.Color:= clRed; 
end; 

... это предполагает, что запись:

type 
    PTreeData = ^TTreeData; 
    TTreeData = record 
    Column0: String; 
    Column1: String; 
    Column2: String; 
    end; 

... объявления d следующий блок:

unit vstButton; 


interface 

uses 
    Classes, SysUtils, Forms, Controls, Graphics, Dialogs, VirtualTrees, 
    messages, windows, StdCtrls, ShlObj; 

type 
    TStringEditLink = class(TInterfacedObject, IVTEditLink) 
    private 
    FEdit: TWinControl; 
    FTree: TVirtualStringTree; 
    FNode: PVirtualNode; 
    FColumn: Integer; 
    FSelectedFolder: string; 
    protected 
    procedure ButtonClick(Sender: TObject); 
    public 
    destructor Destroy; override; 
    function BeginEdit: Boolean; stdcall; 
    function CancelEdit: Boolean; stdcall; 
    function EndEdit: Boolean; stdcall; 
    function GetBounds: TRect; stdcall; 
    function PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean; stdcall; 
    procedure ProcessMessage(var Message: TMessage); stdcall; 
    procedure SetBounds(R: TRect); stdcall; 
    end; 

    function GetFolderDialog(Handle: Integer; Caption: string; var strFolder: string): Boolean; 

implementation 

destructor TStringEditLink.Destroy; 
begin 
    FEdit.Free; 
    inherited; 
end; 

procedure TStringEditLink.ButtonClick(Sender: TObject); 
var 
    s: string; 
begin 
    s := 'c:\'; 
    if GetFolderDialog(Application.Handle, 'Select a folder', s) then 
    FSelectedFolder := s; 

    FTree.EndEditNode; 
    FTree.setfocus; 
end; 

function TStringEditLink.BeginEdit: Boolean; 
begin 
    Result := True; 
    FSelectedFolder := FTree.Text[FNode, FColumn]; 
    TButton(FEdit).CAption := FTree.Text[FNode, FColumn]; 
    FEdit.Show; 
    FEdit.SetFocus; 
end; 

function TStringEditLink.CancelEdit: Boolean; 
begin 
    Result := True; 
    FEdit.Hide; 
    FTree.EndEditNode; 
    FTree.setfocus; 
end; 

function TStringEditLink.EndEdit: Boolean; 
var 
    S: WideString; 
begin 
    Result := True; 
    FTree.Text[FNode, FColumn] := FSelectedFolder; 

    FTree.InvalidateNode(FNode); 
    FEdit.Hide; 
    FTree.SetFocus; 
end; 

function TStringEditLink.GetBounds: TRect; 
begin 
    Result := FEdit.BoundsRect; 
end; 

function TStringEditLink.PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean; 
begin 
    Result := True; 
    FTree := Tree as TVirtualStringTree; 
    FNode := Node; 
    FColumn := Column; 

    FEdit.Free; 
    FEdit := nil; 

    FEdit := TButton.Create(nil); 
    with FEdit as TButton do 
    begin 
      Visible := False; 
      Parent := Tree; 
      Font.Color := FTree.Colors.HeaderHotColor; 
      OnClick := ButtonClick; 
     end; 
end; 

procedure TStringEditLink.ProcessMessage(var Message: TMessage); 
begin 
    FEdit.WindowProc(Message); 
end; 

procedure TStringEditLink.SetBounds(R: TRect); 
var 
    Dummy: Integer; 
begin 
    FTree.Header.Columns.GetColumnBounds(FColumn, Dummy, R.Right); 
    FEdit.BoundsRect := R; 
end; 

//------------------------------------------------------------------------------\\ 

function BrowseCallbackProc(hwnd: HWND; uMsg: UINT; lParam: LPARAM; lpData: LPARAM): Integer; stdcall; 
begin 
    if (uMsg = BFFM_INITIALIZED) then 
    SendMessage(hwnd, BFFM_SETSELECTION, 1, lpData); 
    BrowseCallbackProc := 0; 
end; 

function GetFolderDialog(Handle: Integer; Caption: string; var strFolder: string): Boolean; 
const 
    BIF_STATUSTEXT   = $0004; 
    BIF_NEWDIALOGSTYLE  = $0040; 
    BIF_RETURNONLYFSDIRS  = $0080; 
    BIF_SHAREABLE   = $0100; 
    BIF_USENEWUI    = BIF_EDITBOX or BIF_NEWDIALOGSTYLE; 

var 
    BrowseInfo: TBrowseInfo; 
    ItemIDList: PItemIDList; 
    JtemIDList: PItemIDList; 
    Path: PChar; 
begin 
    Result := False; 
    Path := StrAlloc(MAX_PATH); 
    SHGetSpecialFolderLocation(Handle, CSIDL_DRIVES, JtemIDList); 
    with BrowseInfo do 
    begin 
    hwndOwner := GetActiveWindow; 
    pidlRoot := JtemIDList; 
    SHGetSpecialFolderLocation(hwndOwner, CSIDL_DRIVES, JtemIDList); 

    { return display name of item selected } 
    pszDisplayName := StrAlloc(MAX_PATH); 

    { set the title of dialog } 
    lpszTitle := PChar(Caption);//'Select the folder'; 
    { flags that control the return stuff } 
    lpfn := @BrowseCallbackProc; 
    { extra info that's passed back in callbacks } 
    lParam := LongInt(PChar(strFolder)); 
    end; 

    ItemIDList := SHBrowseForFolder(BrowseInfo); 

    if (ItemIDList <> nil) then 
    if SHGetPathFromIDList(ItemIDList, Path) then 
    begin 
     strFolder := Path; 
     Result := True 
    end; 
end; 

End. 

выше код основан на коде найти на этом сайте: http://wiki.freepascal.org/VirtualTreeview_Example_for_Lazarus Если посмотреть на блок vstButton, чтобы получить TEdit или TCombo ... и т.д. ... просто замените любую ссылку TButton на TEdit или TCombo и т. д. ... настройте события для нее и т. д. В приведенном выше коде ссылка действительно использует TCombo

этот сайт помог мне узнать, как использовать virtualtreeview приведенный выше код вставляет в каждую ячейку, и когда вы нажимаете на кнопку, она откроет диалог BrowseForFolder и вернет результат обратно в ячейку virtualtreeview Надеюсь, что это поможет

Вам нужна кнопка, видимая в столбце ячейки все время? Смогла смоделировать кнопку с изображением ... как выпадающий знак на одной стороне ячейки

+0

Это должно сработать ... :) Я не думал о том, чтобы посмотреть на вики Lazarus – Brad