2013-05-17 8 views
1

Delphi XE2 또는 XE3에서 Outlook 2013 목록과 유사한 목록 상자를 만들려면 어떻게해야합니까?Outlook 2013과 같은 목록 상자를 만들려면 어떻게해야합니까?

또는 Outlook 2013의 다른 목록입니까?

어떻게 델파이 XE2 또는 XE3에서 비슷한 것을 얻을 수 있습니까?

감사

enter image description here

+0

정확히 어떤 목록을 언급하고 있습니까? 스크린 샷을 제공 할 수 있습니까? Office는 표준 Win32 UI 컨트롤 대신 사용자 지정 UI 컨트롤을 사용하는 것으로 유명합니다. –

+0

흐릿한 스크린 샷이 거의 보이지 않습니다. 하지만 그것은 목록보기 컨트롤이라고 말하고 싶습니다. – OnTheFly

+0

스택 오버플로는 레이아웃의 고정 너비에 맞게 이미지의 크기를 조절합니다. 이미지를 단독으로 보시면 풀 사이즈 스크린 샷 인 @User를보실 수 있습니다. 게다가 우리가 다루고있는 컨트롤을 알 수있을 정도로 선명한 이미지 일 필요는 없습니다. –

답변

6

TListViewListGroups과 유사한 작업을 수행 할 수 있습니다. Delphi documentationListGroups을 사용하는 예가 있습니다 (XE4에 대한 링크이지만 XE2 및 XE3에서도 작동합니다). 찾고있는 이미지를 제공하지는 않지만 이미지를 사용하는 방법을 보여주기 때문에 이미지를 가져올 수 있어야합니다.

(아래 코드는 해당 링크의 코드를 직접 복사/붙여 넣기하는 것이 아니며 해당 코드에는 오류 및 누락이 있으므로주의해야합니다.) 수정, 컴파일 및 실행하여 먼저 여기에 게시하기 전에 수정하십시오.)

새 VCL 양식 응용 프로그램에 TListView 및 TImageList를 놓습니다. TImageList의 이름을 DigitsLetters으로 변경하고 다음 코드를 폼에 추가합니다 (보통 때와 마찬가지로 Object Inspector에서 FormCreateFormDestroy을 만들고 코드를 이벤트 처리기에 붙여 넣은 다음 privateGetImageFromAscii의 선언을 추가합니다). 형태 선언 부)

procedure TForm1.FormCreate(Sender: TObject); 
var 
    Group: TListGroup; 
    ListItem: TListItem; 
    Image: TBitmap; 
    c: Char; 
begin 
    { align the list view to the form } 
    ListView1.Align := alClient; 

    { center and stretch the form to fit the screen } 
    Self.Position := poScreenCenter; 
    Self.Height := 600; 
    Self.Width := 800; 

    { 
    change the view style of the list view 
    such that the icons are displayed 
    } 
    ListView1.ViewStyle := vsIcon; 

    { enable group view } 
    ListView1.GroupView := True; 

    { create a 32 by 32 image list } 
    DigitsLetters := TImageList.CreateSize(32, 32); 

    { 
    generate the DigitsLetters image list with the digits, 
    the small letters and the capital letters 
    } 
    GetImagesFromASCII('0', '9'); 
    GetImagesFromASCII('a', 'z'); 
    GetImagesFromASCII('A', 'Z'); 

    { 
    add an empty image to the list 
    used to emphasize the top and bottom descriptions 
    of the digits group 
    } 
    Image := TBitmap.Create; 
    Image.Height := 32; 
    Image.Width := 32; 
    DigitsLetters.Add(Image, nil); 
    Image.Destroy; 

    { create a title image for the small letters category } 
    Image := TBitmap.Create; 
    Image.Height := 32; 
    Image.Width := 32; 
    Image.Canvas.Brush.Color := clYellow; 
    Image.Canvas.FloodFill(0, 0, clYellow, fsBorder); 
    Image.Canvas.Font.Name := 'Times New Roman'; 
    Image.Canvas.Font.Size := 14; 
    Image.Canvas.Font.Color := clRed; 
    Image.Canvas.TextOut(3, 5, 'a..z'); 
    DigitsLetters.Add(Image, nil); 
    Image.Destroy; 

    { create a title image for the capital letters category } 
    Image := TBitmap.Create; 
    Image.Height := 32; 
    Image.Width := 32; 
    Image.Canvas.Brush.Color := clYellow; 
    Image.Canvas.FloodFill(0, 0, clYellow, fsBorder); 
    Image.Canvas.Font.Name := 'Times New Roman'; 
    Image.Canvas.Font.Size := 13; 
    Image.Canvas.Font.Color := clRed; 
    Image.Canvas.TextOut(2, 5, 'A..Z'); 
    DigitsLetters.Add(Image, nil); 
    Image.Destroy; 

    { associate the image list with the list view } 
    ListView1.LargeImages := DigitsLetters; 
    ListView1.GroupHeaderImages := DigitsLetters; 

    { set up the digits group } 
    Group := ListView1.Groups.Add; 
    Group.State := [lgsNormal, lgsCollapsible]; 
    Group.Header := 'Digits'; 
    Group.HeaderAlign := taCenter; 
    Group.Footer := 'End of the Digits category'; 
    Group.FooterAlign := taCenter; 
    Group.Subtitle := 'The digits from 0 to 9'; 

    { 
    use the empty image as the title image 
    to emphasize the top and bottom descriptions 
    } 
    Group.TitleImage := DigitsLetters.Count - 3; 

    { create the actual items in the digits group } 
    for c := '0' to '9' do 
    begin 
    // add a new item to the list view 
    ListItem := ListView1.Items.Add; 

    // ...customize it 
    ListItem.Caption := c + ' digit'; 
    ListItem.ImageIndex := Ord(c) - Ord('0'); 

    // ...and associate it with the digits group 
    ListItem.GroupID := Group.GroupID; 
    end; 

    { set up the small letters group } 
    Group := ListView1.Groups.Add; 
    Group.State := [lgsNormal, lgsCollapsible]; 
    Group.Header := 'Small Letters'; 
    Group.HeaderAlign := taRightJustify; 
    Group.Footer := 'End of the Small Letters category'; 
    Group.FooterAlign := taLeftJustify; 
    Group.Subtitle := 'The small letters from ''a'' to ''z'''; 
    Group.TitleImage := DigitsLetters.Count - 2; 

    { create the actual items in the small letters group } 
    for c := 'a' to 'z' do 
    begin 
    // add a new item to the list view 
    ListItem := ListView1.Items.Add; 

    // ...customize it 
    ListItem.Caption := 'letter ' + c; 
    ListItem.ImageIndex := Ord(c) - Ord('a') + 10; 

    // ...and associate it with the small letters group 
    ListItem.GroupID := Group.GroupID; 
    end; 

    { 
    to see how the NextGroupID property can be used, 
    the following lines of code show how an item can be associated 
    with a group ID, prior to creating the group 
    } 

    { create the actual items in the capital letters group } 
    for c := 'A' to 'Z' do 
    begin 
    // add a new item to the list view 
    ListItem := ListView1.Items.Add; 

    // ...customize it 
    ListItem.Caption := 'letter ' + c; 
    ListItem.ImageIndex := Ord(c) - Ord('A') + 36; 

    // ...and associate it with the capital letters group 
    ListItem.GroupID := ListView1.Groups.NextGroupID; 
    end; 

    { set up the capital letters group } 
    Group := ListView1.Groups.Add; 
    Group.State := [lgsNormal, lgsCollapsible]; 
    Group.Header := 'Capital Letters'; 
    Group.HeaderAlign := taRightJustify; 
    Group.Footer := 'End of the Capital Letters category'; 
    Group.FooterAlign := taLeftJustify; 
    Group.Subtitle := 'The capital letters from ''A'' to ''Z'''; 
    Group.TitleImage := DigitsLetters.Count - 1; 

end; 

procedure TForm1.FormDestroy(Sender: TObject); 
begin 
    { remove the image list from memory } 
    DigitsLetters.Destroy; 
end; 

{ 
Generates a series of images for the characters 
starting with ASCII code First and ending with Last. 
All images are added to the DigitsLetters variable. 
} 
procedure TForm1.GetImagesFromASCII(First, Last: Char); 
var 
    Image: TBitmap; 
    c: Char; 
begin 
    for c := First to Last do 
    begin 
    Image := TBitmap.Create; 
    Image.Height := 32; 
    Image.Width := 32; 
    Image.Canvas.Font.Name := 'Times New Roman'; 
    Image.Canvas.Font.Size := 22; 
    Image.Canvas.TextOut((Image.Width - Image.Canvas.TextWidth(c)) div 2, 0, c); 
    DigitsLetters.Add(Image, nil); 
    Image.Destroy; 
    end; 
end; 

결과합니다 (DigitsSmall Letters기로 도시)가 접힌 :

Sample ListView/ListGroups image

+0

미안하지만이 코드는 B4를 통해 살펴 보았지만 아무데도 나에게주지 않았지만 뒤에 숨어 있다고 확신합니다. – Dreamer64

4

Outlook에서 제어 표준 목록 상자가 아닙니다. Outlook 2010에서는 "SUPERGRID"클래스의 창으로, Outlook 2013이 비슷하다고 상상합니다.

Outlook 개발자가 직접 작성하고 컨트롤을 작성할 수는 있지만 실제로 관심있는 것보다 큰 프로젝트 일 수 있습니다. 더 간단한 작업은 일반 TListBox을 사용하고 OnDrawItem 이벤트를 처리하는 것입니다. 항목의 높이를 높이려면 OnMeasureItem 이벤트를 처리 할 수 ​​있습니다.

컨트롤에 확장 가능 및 축소 가능 항목 그룹이 포함되도록하려면 대신 트리 컨트롤로 시작할 수 있습니다. TTreeView도 맞춤형으로 그릴 수 있습니다. 사용자 정의 가능성을 높이려면 TVirtualStringTree을 시도해보십시오.

+0

감사합니다. SUPERGRID 클래스를 돌보고 무엇을 얻을 수 있는지 알아 봅니다. – Dreamer64

0

내가 필요한 작업을 수행하는 데 가장 적합한 코드를 찾았습니다. 위의 이미지를 완벽하게 볼 수 있습니다.

unit Unit1; 

interface 

uses 
    Contnrs, 
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
    Dialogs, ImgList, ComCtrls; 

type 
    TGroupItem = class 
    private 
    fItems : TObjectList; 
    fCaption: string; 
    fListItem: TListItem; 
    fExpanded: boolean; 
    function GetItems: TObjectList; 
    public 
    constructor Create(const caption : string; const numberOfSubItems : integer); 
    destructor Destroy; override; 

    procedure Expand; 
    procedure Collapse; 

    property Expanded : boolean read fExpanded; 
    property Caption : string read fCaption; 
    property Items : TObjectList read GetItems; 
    property ListItem : TListItem read fListItem write fListItem; 
    end; 

    TItem = class 
    private 
    fTitle: string; 
    fValue: string; 
    public 
    constructor Create(const title, value : string); 
    property Title: string read fTitle; 
    property Value : string read fValue; 
    end; 


    TForm1 = class(TForm) 
    lvGroups: TListView; 
    listViewImages: TImageList; 
    procedure FormCreate(Sender: TObject); 
    procedure FormDestroy(Sender: TObject); 
    procedure lvGroupsAdvancedCustomDrawItem(Sender: TCustomListView; 
     Item: TListItem; State: TCustomDrawState; Stage: TCustomDrawStage; 
     var DefaultDraw: Boolean); 
    procedure lvGroupsDblClick(Sender: TObject); 
    private 
    procedure ClearListViewGroups; 
    procedure FillListViewGroups; 
    public 
    { Public declarations } 
    end; 

var 
    Form1: TForm1; 

implementation 

{$R *.dfm} 
procedure TForm1.ClearListViewGroups; 
var 
    li : TListItem; 
    qng : TGroupItem; 
begin 
    for li in lvGroups.Items do 
    begin 
    if TObject(li.Data) is TGroupItem then 
    begin 
     qng := TGroupItem(li.Data); 
     FreeAndNil(qng); 
    end; 
    end; 
    lvGroups.Clear; 
end; 

procedure TForm1.FillListViewGroups; 

    procedure AddGroupItem(gi : TGroupItem); 
    var 
    li : TListItem; 
    begin 
    li := lvGroups.Items.Add; 

    li.Caption := gi.Caption; 
    li.ImageIndex := 1; //collapsed 

    li.Data := gi; 
    gi.ListItem := li; //link "back" 
    end; 
begin 
    ClearListViewGroups; 

    AddGroupItem(TGroupItem.Create('Group A', 3)); 
    AddGroupItem(TGroupItem.Create('Group B', 1)); 
    AddGroupItem(TGroupItem.Create('Group C', 4)); 
    AddGroupItem(TGroupItem.Create('Group D', 5)); 
AddGroupItem(TGroupItem.Create('Group D', 5)); 
    AddGroupItem(TGroupItem.Create('Group D', 5)); 
    AddGroupItem(TGroupItem.Create('Group D', 5)); 

end; 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    FillListViewGroups; 
end; 

procedure TForm1.FormDestroy(Sender: TObject); 
begin 
    ClearListViewGroups; 
end; 

procedure TForm1.lvGroupsAdvancedCustomDrawItem(Sender: TCustomListView; 
    Item: TListItem; State: TCustomDrawState; Stage: TCustomDrawStage; 
    var DefaultDraw: Boolean); 
begin 
    //bold group items 
    if TObject(item.Data) is TGroupItem then 
    begin 
    lvGroups.Canvas.Font.Style := lvGroups.Canvas.Font.Style + [fsBold]; 
    end; 
end; 

//handles TListView OnDblClick even 
procedure TForm1.lvGroupsDblClick(Sender: TObject); 
var 
    hts : THitTests; 
    gi : TGroupItem; 
begin 
    inherited; 

    hts := lvGroups.GetHitTestInfoAt(lvGroups.ScreenToClient(Mouse.CursorPos).X, lvGroups.ScreenToClient(Mouse.CursorPos).y); 

    if (lvGroups.Selected <> nil) then 
    begin 
    if TObject(lvGroups.Selected.Data) is (TGroupItem) then 
    begin 
     gi := TGroupItem(lvGroups.Selected.Data); 

     if NOT gi.Expanded then 
     gi.Expand 
     else 
     gi.Collapse; 
    end; 
    end; 
end; 


{$region 'TGroupItem'} 

procedure TGroupItem.Collapse; 
var 
    li : TListItem; 
begin 
    if NOT Expanded then Exit; 

    ListItem.ImageIndex := 1; 
    fExpanded := false; 

    li := TListView(ListItem.ListView).Items[ListItem.Index + 1]; 
    while (li <> nil) AND (TObject(li.Data) is TItem) do 
    begin 
    TListView(ListItem.ListView).Items.Delete(li.Index); 
    li := TListView(ListItem.ListView).Items[ListItem.Index + 1]; 
    end; 
end; 

constructor TGroupItem.Create(const caption: string; const numberOfSubItems : integer); 
var 
    cnt : integer; 
begin 
    fCaption := caption; 

    for cnt := 1 to numberOfSubItems do 
    begin 
    Items.Add(TItem.Create(caption + ' item ' + IntToStr(cnt), IntToStr(cnt))); 
    end; 
end; 

destructor TGroupItem.Destroy; 
begin 
    FreeAndNil(fItems); 
    inherited; 
end; 

procedure TGroupItem.Expand; 
var 
    cnt : integer; 
    item : TItem; 
begin 
    if Expanded then Exit; 

    ListItem.ImageIndex := 0; 
    fExpanded := true; 

    for cnt := 0 to -1 + Items.Count do 
    begin 
    item := TItem(Items[cnt]); 
    with TListView(ListItem.ListView).Items.Insert(1 + cnt + ListItem.Index) do 
    begin 
     Caption := item.Title; 
     SubItems.Add(item.Value); 
     Data := item; 
     ImageIndex := -1; 
    end; 
    end; 
end; 

function TGroupItem.GetItems: TObjectList; 
begin 
    if fItems = nil then fItems := TObjectList.Create(true); 
    result := fItems; 
end; 
{$endregion} 

{$region 'TItem' } 

constructor TItem.Create(const title, value: string); 
begin 
    fTitle := title; 
    fValue := value; 
end; 
{$endregion} 

end.