Страница 3 из 3

Re: CheckListBox: удалить выбранные итемсы

Добавлено: 14 фев 2007, 16:55
somewhere
Сейчас_не_спящий, ошибка твоя наверняка в том, что после удаления одного контрола ты идешь к следующему. А при удалении контрола все остальные после него сдвигаются. И если удаляешь, например, 5 айтем, то на место него встанет 6-ой. Вот и получается у тебя все через один. Тебе надо менять переменую в For на 1 меньше в удалении, но так как компилер тебе врядли даст это сделать, тебе надо юзать:

Код: Выделить всё

X := 0;
While x<ControlCount do
begin
if ....... then 
    begin
    ....
    dec(x);
    end;
inc(x);
end;

Re: CheckListBox: удалить выбранные итемсы

Добавлено: 15 фев 2007, 00:40
Сейчас_не_спящий
&quot писал(а):Сейчас_не_спящий, ошибка твоя наверняка в том, что после удаления одного контрола ты идешь к следующему. А при удалении контрола все остальные после него сдвигаются. И если удаляешь, например, 5 айтем, то на место него встанет 6-ой. Вот и получается у тебя все через один. Тебе надо менять переменую в For на 1 меньше в удалении, но так как компилер тебе врядли даст это сделать, тебе надо юзать:
Представленынй мной выше код пока работает без сбоев, тестировалось несколькими юзерами из сети, пока сбоев не нашли. Хотя уверен, что сократь и оптимизировать это можно, просто пока не хватает чего-то... :)
А так как это форум, а не чат, вылажу всё заного (что бы те, кому интересно и не догоняют смогли внедрить код и попытаться разобраться в нём (пояснения писать не буду, чисто код, если что спрашивайте):
Пример
Задача: есть ComboBox1. По нажатию на Button1 отображаемую строку в ComboBox1 надо добавить в CheckListBox1, причём повторяться записи не должны (в случае повторения записи выдает об этом сообщение типа "Error"). По нажатию на Button2 (Удалить) должны удаляться выбранные в CheckListBox1 итемсы (items или, по простому, выбранные компоненты). Причём, если нет ни одного выбранного компонента, кнопка активной быть не должна (вполне логично: если ничего для удаления не выбрано, так зачем же тогда далать активной кнопку?). Есть ещё Button3 (очистить, который удаляет все записи в CheckListBox1 и, как само собой разумеется, делает Button2 и Button3 не активными).
Решается эта задача так:

Код: Выделить всё

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, CheckLst;

type
  TForm1 = class(TForm)
    ComboBox1: TComboBox;
    CheckListBox1: TCheckListBox;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure CheckListBox1ClickCheck(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
i : integer;
c : integer;
begin
  c := 0;
  for i := 0 to CheckListBox1.Count -1 do
  if (ComboBox1.Text = CheckListBox1.Items[i]) then
  begin
    Inc (c);
    MessageDlg('Элемент "' + ComboBox1.Text + '" уже выбран, выберите другой', mtError, [mbOk], 0);
    ComboBox1.SetFocus;
  end;
if c < 1 then
begin
  CheckListBox1.Items.Add(ComboBox1.Text);
  Button3.Enabled := true;
end;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  CheckListBox1.Items.Clear;
  Button1.SetFocus;
  Button2.Enabled := False;
  Button3.Enabled := False;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
i : integer;
begin
  i := 0;
  while i < CheckListBox1.Count do
  if CheckListBox1.Checked[i] then
  CheckListBox1.Items.Delete(i)
  else
  Inc(i);
  if (CheckListBox1.Count -1 < 0) then
  begin
    Button1.SetFocus;
    Button2.Enabled := False;
    Button3.Enabled := False;
  end;
end;

procedure TForm1.CheckListBox1ClickCheck(Sender: TObject);
var
i : integer;
c : boolean;
begin
  c := false;
  for i := 0 to CheckListBox1.Items.Count -1 do
  begin
    if CheckListBox1.Checked[i] then
    begin
      c := true;
      break;
    end;
  end;
  Button2.Enabled := c;
end;

end.
Если кого-то затрудняет выполнить подобную задачу с 2 CheckListBox'ами (например, если установлен RadioButton или RadioGroup1, которые определяют в какой CheckListBox добавить запись, могу скинуть код, сбоев пока не довал.
Всё тестировалось юзерами...=))
Как понимаю, тему можно закрывать.

Re: CheckListBox: удалить выбранные итемсы

Добавлено: 15 фев 2007, 14:55
LAngel
somewhere писал(а):Сейчас_не_спящий, ошибка твоя наверняка в том, что после удаления одного контрола ты идешь к следующему. А при удалении контрола все остальные после него сдвигаются.
Я в таких случаях обычно пользуюсь "счетчиком наоборот", т.е:

Код: Выделить всё

var
  i: Integer
begin
  For i := ControlsCount-1 downto 0 do
  begin
    if .... then Control[i].Delete;
  end;
end;
Тогда порядок не нарушается.