我正在研究Delphi 7.我有一个TListBox和一个带有两列的TStringGrid(没有固定的行或列)。我在TListBox中有如下数据:
可用元素 - a123(a123) 可用元素 - a1234(a1234) 可用元素 - a12345(a12345)
TStringGrid的数据如下:
Column1 Column2
a1可用元素 - a1 a2可用元素 - a12
如果我选择TListbox中的第一项,即a123并执行以下按钮点击事件程序,则最后一项数据即a12345将被移入网格。
在下面的代码中,是否有人可以将重点放在我做错的事情上。下面的代码将TListbox中的seleted项移动到TStringgird的两列:
procedure TForm1.btnMoveLeftClick(Sender: TObject);
var
sString : String;
i : Integer;
begin
for i := 0 to ListBox1.Items.Count - 1 do
begin
{-- Is this status selected? --}
if ListBox1.Selected[i] then
begin
sString := Trim(ListBox1.Items[i]);
{-- Delete selected status. --}
ListBox1.Items.Delete (i);
if ((grdVFormDetails.RowCount >= 1) And (Trim(grdVFormDetails.Cells[0, 0]) <> EmptyStr)) then
grdVFormDetails.RowCount := grdVFormDetails.RowCount+1;
grdVFormDetails.Cols[1].Add(Copy(sString, 1, Pos('(', sString) - 1));
sString := Copy(sString, Pos('(', sString) + 1, Length(sString));
sString := Copy(sString, Pos('(', sString) + 1, Length(sString) - 1);
grdVFormDetails.Cols[0].Add(sString);
break;
end;
end;
end;
答案 0 :(得分:2)
永远不要删除FOR循环中的TList项。
这一行的问题:
ListBox1.Items.Delete (i);
循环从i:= 0变为2.项目 - 0被选中并删除它。我们下次重复的是什么? i = 1但是这里只剩下2个项目而不是3个(所有后续项目都被移动),我指向最后一个项目而不是第二个项目。在i = 3的下一次重复时,我们将得到“Index out of bound”错误。您应该仅在FOR循环后删除Item以避免此问题。
procedure TForm1.btnMoveLeftClick(Sender: TObject);
var
sString : String;
i : Integer;
k: integer;
begin
k:=-1;
for i := 0 to ListBox1.Items.Count - 1 do
begin
{-- Is this status selected? --}
if ListBox1.Selected[i] then
begin
sString := Trim(ListBox1.Items[i]);
{-- Delete selected status. --}
k:=i;
if ((grdVFormDetails.RowCount >= 1) And (Trim(grdVFormDetails.Cells[0, 0]) <> EmptyStr)) then
grdVFormDetails.RowCount := grdVFormDetails.RowCount+1;
grdVFormDetails.Cols[1].Add(Copy(sString, 1, Pos('(', sString) - 1));
sString := Copy(sString, Pos('(', sString) + 1, Length(sString));
sString := Copy(sString, Pos('(', sString) + 1, Length(sString) - 1);
grdVFormDetails.Cols[0].Add(sString);
break;
end;
end;
if k>=0 then ListBox1.Items.Delete (k);
end;
答案 1 :(得分:1)
假设您要解析输入字符串,如下所示:
'Some text (comment) etc. (12345)'
进入一个带有修剪字符串的部分,从输入字符串的开头到第一个左括号(从头到尾)得到一个这样的值:
'Some text (comment) etc.'
和输入字符串的最后一个括号内的字符串:
'12345'
如果是这样,您可以使用以下代码。请注意,预计将通过右括号终止列表框项目。如果需要,您可以查看此代码的commented version
或下载sample project
。
以下是将焦点项目从列表框移动到字符串网格的部分:
procedure TForm1.MoveLeftButtonClick(Sender: TObject);
var
S: string;
I: Integer;
ItemID: string;
ItemText: string;
begin
if ListBox1.ItemIndex = -1 then
Exit;
S := ListBox1.Items[ListBox1.ItemIndex];
for I := Length(S) - 1 downto 1 do
begin
if S[I] = '(' then
begin
ItemID := Trim(Copy(S, I + 1, Length(S) - I - 1));
ItemText := Trim(Copy(S, 1, I - 1));
with StringGrid1 do
begin
if (Cells[0, RowCount - 1] <> '') and
(Cells[1, RowCount - 1] <> '')
then
RowCount := RowCount + 1;
Cells[0, RowCount - 1] := ItemID;
Cells[1, RowCount - 1] := ItemText;
end;
ListBox1.Items.Delete(ListBox1.ItemIndex);
Break;
end;
end;
end;
以下是将所选行从字符串网格移动到列表框的部分:
procedure TForm1.MoveRightButtonClick(Sender: TObject);
var
I: Integer;
RowIndex: Integer;
begin
RowIndex := StringGrid1.Selection.Top;
if (StringGrid1.Cells[0, RowIndex] <> '') and
(StringGrid1.Cells[1, RowIndex] <> '') then
begin
ListBox1.Items.Add(
Trim(StringGrid1.Cells[1, RowIndex]) + ' (' +
Trim(StringGrid1.Cells[0, RowIndex]) + ')'
);
for I := RowIndex to StringGrid1.RowCount - 2 do
StringGrid1.Rows[I].Assign(StringGrid1.Rows[I + 1]);
if StringGrid1.RowCount > 1 then
StringGrid1.RowCount := StringGrid1.RowCount - 1
else
begin
StringGrid1.Cells[0, 0] := '';
StringGrid1.Cells[1, 0] := '';
end;
end;
end;
答案 2 :(得分:0)
我目前没有安装Delphi,但据我记得,如果ListBox1.Selected [i]则不会给你正确的结果。你需要先得到这个项目, 他们检查项目是否被选中。
答案 3 :(得分:0)
如果ListBox中没有多重选择,最好使用ItemIndex属性,该属性为您提供所选项目的索引,因此您无需循环检查列表中的所有项目。 / p>
像这样:
procedure TForm1.btnMoveLeftClick(Sender: TObject);
var
sString : String;
i : Integer;
begin
if ListBox1.ItemIndex <> -1 then
begin
sString := Trim(ListBox1.Items[ListBox1.ItemIndex]);
//do all your processing here
//and at the end:
ListBox1.Items.Delete(ListBox1.ItemIndex);
end
end;