2015-06-01 3 views
6

Мне нужно добавить кнопку (возможно, TSpeedButton?) На каждый элемент ComboBox. Когда один щелчок на кнопке, соответствующий элемент удаляется из списка. Например:ComboBox: кнопка на каждом элементе (для удаления элемента из списка)

enter image description here

Я видел подобное обсуждение SpeedButtons в строковых сетках (здесь: TStringGrid with SpeedButtons), но я не знаю, как реализовать все эти вещи на ComboBox. Не могли бы вы дать мне несколько советов или ссылок для дальнейшего чтения по этой теме.

+0

Не обязательно быть точно TSpeedButton, но кнопка с обработчиком OnClick. Какие-либо предложения? – Alex

+0

Я отредактировал вопрос .. Имейте изображение, чтобы проиллюстрировать, но Rep слишком низко. – Alex

+1

В любом случае, я думаю, вы будете искать пользовательские нарисовать комбо-элементы, включая кнопку удаления, а затем обнаружить клики. Лично я бы пытался найти другой интерфейс. –

ответ

5

В дополнение к комментариям пользователя, в отношении которых я согласен, решение вопроса на самом деле не так уж сложно.

Вы можете сделать это, установив Style свойство csOwnerDrawFixed, рисование, самостоятельно в OnDrawItem случае, и удаление выбранного элемента в OnSelect случае, например, следующим образом:

unit Unit1; 

interface 

uses 
    Winapi.Windows, System.Classes, Vcl.Controls, Vcl.Forms, Vcl.StdCtrls, 
    Vcl.Imaging.PNGIMage; 

type 
    TForm1 = class(TForm) 
    ComboBox1: TComboBox; 
    procedure FormCreate(Sender: TObject); 
    procedure FormDestroy(Sender: TObject); 
    procedure ComboBox1DrawItem(Control: TWinControl; Index: Integer; 
     Rect: TRect; State: TOwnerDrawState); 
    procedure ComboBox1Select(Sender: TObject); 
    private 
    FDeleteGraphic: TPNGImage; 
    FDeleteRect: TRect; 
    end; 

implementation 

{$R *.dfm} 

{ TForm1 } 

procedure TForm1.ComboBox1DrawItem(Control: TWinControl; Index: Integer; 
    Rect: TRect; State: TOwnerDrawState); 
begin 
    ComboBox1.Canvas.FillRect(Rect); 
    if Index >= 0 then 
    ComboBox1.Canvas.TextOut(Rect.Left + 2, Rect.Top, ComboBox1.Items[Index]); 
    if (odSelected in State) and not (odComboBoxEdit in State) then 
    begin 
    FDeleteRect := Rect; 
    FDeleteRect.Left := FDeleteRect.Right - FDeleteGraphic.Width; 
    ComboBox1.Canvas.Draw(FDeleteRect.Left, FDeleteRect.Top, FDeleteGraphic); 
    end; 
end; 

procedure TForm1.ComboBox1Select(Sender: TObject); 
var 
    MousePos: TPoint; 
begin 
    MousePos := ComboBox1.ScreenToClient(Mouse.CursorPos); 
    MousePos.Offset(0, -ComboBox1.Height); 
    if PtInRect(FDeleteRect, MousePos) then 
    begin 
    ComboBox1.Items.Delete(ComboBox1.ItemIndex); 
    ComboBox1.Invalidate; 
    end; 
end; 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    FDeleteGraphic := TPNGImage.Create; 
    FDeleteGraphic.LoadFromFile('H:\Icons\FamFam Common\Delete.png'); 
end; 

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

end. 

С этим результатом :

Screen shot

Вы можете (повторно) сохранить предыдущий ItemIndex настройки. Настройте свои пожелания.

+0

Несомненно, 'OnSelect' может быть запущен с помощью действий клавиатуры. –

+0

@ Давид Конечно. Если пользователь решит позиционировать курсор мыши точно в пределах значка удаления, то, возможно, удар по Enter может указывать на желаемое удаление. В противном случае установите 'FDeleteRect.Width: = -1;' в событии 'OnKeyDown'. – NGLN

+0

Это не кнопки, а изображения. –

Смежные вопросы