В него слямзенной функцией добавляем из нескольких полей текст. Добавляет очень криво. В Item он добавляет сначала пустую строку потом на следующей введенный текст, а в SubItem наоборот. Что делать не понятно О_О
Заранее спасибо.
Код
procedure TForm1.bbAddClick(Sender: TObject); var ListItem : TListItem; begin ListItem := List.Items.Add;
А как сделать поиск по subitem'ам? А то он у меня ищет только по Caption'ам видимо. Функция такая (тоже слямзенная ]: )
Код
procedure TForm1.bbSearchClick(Sender: TObject); var lvItem: TListItem; begin lvItem := List.FindCaption(0, edLastName.Text, True, True, False); if lvItem <> nil then begin List.Selected := lvItem; lvItem.MakeVisible(True); List.SetFocus; end else ShowMessage('Запись не найдена');
Вообще-то это есть в DRKB (ссылка - в самом начале страницы):
function FindListViewItem(lv: TListView; const S: string; column: Integer): TListItem;
var i: Integer; found: Boolean; begin Assert(Assigned(lv)); Assert((lv.viewstyle = vsReport) or (column = 0)); Assert(S <> ''); for i := 0 to lv.Items.Count - 1 do begin Result := lv.Items[i]; if column = 0 then found := AnsiCompareText(Result.Caption, S) = 0 else if column > 0 then found := AnsiCompareText(Result.SubItems[column - 1], S) = 0 else found := False;
procedure LV_FindAndSelectItems(lv: TListView; const S: string; column: Integer); var i: Integer; found: Boolean; lvItem: TListItem; begin Assert(Assigned(lv)); Assert((lv.ViewStyle = vsReport) or (column = 0)); Assert(S <> ''); for i := 0 to lv.Items.Count - 1 do begin lvItem := lv.Items[i];
if column = 0 then found := AnsiCompareText(lvItem.Caption, S) = 0 else if column > 0 then begin if lvItem.SubItems.Count >= Column then found := AnsiCompareText(lvItem.SubItems[column - 1], S) = 0 else found := False; end else found := False;
if found then begin lv.Selected := lvItem; end; end;
end;
Она выделяет все найденные соответсвтия.
Но! Если использовать ее во второй раз - он добавит новый результ к старому, то есть выделятся строки, найденные за два запроса. Делал так:
Код
for i := 1 to List.Items.Count - 1 do List.Items.Item[i].Selected := false;
он выделение снимает, но все равно скалдывает два результата. Помагает только клик по List: TListView.
Могу показать, как можно определить тот Caption, на котором был Double-Click (вообще GetItemAt не работает с SubItems, а работает только с первым столбцом ЛистВью, элементы которого можно выделить мышью, но с помощью вот такого финта можно это добавить):
var pX, pY: integer;
procedure TForm1.ListView1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin // Запоминаем координаты, где была нажата мышка pX := X; pY := Y; // Чтобы не мучаться с переводом в локальные координаты для ListView end;
// Ну, и собственно обрабатываем двойное нажатие: procedure TForm1.ListView1DblClick(Sender: TObject); var li, root: TListItem; i, curr_left: integer; begin // Сначала пробуем найти итем непосредственно, это сработает только для первого столбца li := ListView1.GetItemAt(pX, pY); if assigned(li) then ShowMessage(li.Caption) else begin
// если мы здесь - это признак того, что дабл-клик был не на первом столбце... // тогда делаем вот что: пробегаем по всем длинам заголовков столбцов, и // накапливаем их длину до тех пор, пока она не превысит координату X нажатия мыши // i := 0; curr_left := ListView1.Columns[0].Width; while (curr_left + ListView1.Columns[i].Width < pX) do begin inc(curr_left, ListView1.Columns[i].Width); inc(i); end;
// теперь находим, какой элемент является "корнем" для искомого SubItem-а root := ListView1.GetItemAt(10, pY);
// Если "корень" найден, и у него есть столько "детей" - то // печатаем Caption соответствующего "ребенка" if (assigned(root)) and (i < root.SubItems.Count) then showmessage(root.SubItems[i]);
end; end;
Можно используя этот код вместо ShowMessage вызывать, например, диалоговое окно, которое будет запрашивать новое значение, и после ввода менять соотв. Caption... Не пробовал, но по-моему должно работать...