我在字符串中生成逗号分隔的名称列表,例如
Mr John Blue, Miss A Green, Mr Posh Hyphenated-Surname, Mr Fred Green, Miss Helen Red, Ms Jean Yellow
我现在想要在一个备忘录框中显示它们,每个行上可以容纳50个字符,以便每行显示尽可能多的名称(以及它们的尾随逗号)。所以上面应该是这样的
Mr John Blue, Miss A Green,
Mr Posh Hyphenated-Surname, Mr Fred Green,
Miss Helen Red, Ms Jean Yellow
我玩过
Memo1.text := WrapText(Mystring,50)
但它在姓氏和姓氏之间的空格处打破了线条,我试过了
Memo1.text := WrapText(MyString, slinebreak, ',' ,50)
强制它只在逗号之后断开但是在空格和逗号处都破坏了。两者都倾向于用连字符打破,我注意到Rob Kennedy对类似问题的回答,即嵌入式引号引起Wrap()的问题,所以像John O'Donald先生这样的名字会引起问题。
我甚至尝试通过计算字符和寻找逗号来完成我自己的功能,但是陷入了多个嵌套的IF(太尴尬地显示了可怕的代码!)
任何人都可以提供任何帮助或代码,说明如何做到这一点?
PS我看过了
和其他类似的帖子,但似乎没有匹配我要找的东西。
设置Memo1.WordWrap:=False;
有很多解决方案,我在这里只展示一个。 但要小心: 如果您使用大量数据,则执行速度很慢
procedure TForm1.AddTextToMemo(needle,xsSrc:string);
var
xsNew:string;
mposOld,mposNew:integer;
start:byte;
begin
xsNew:=xsSrc;
repeat
repeat
mposOld:=mposNew;
mposNew:=Pos(needle,xsSrc);
if mposNew>0 then xsSrc[mposNew]:='*';
until (mposNew > 50) OR (mposNew = 0);
if mposOld > 0 then begin
if xsNew[1] = ' ' then start := 2 else start := 1;
if mposNew = 0 then mposOld:=Length(xsNew);
Memo1.Lines.Add(copy(xsNew,start,mposOld));
if mposNew = 0 then exit;
xsNew:=copy(xsNew,mposOld+1,Length(xsNew)-mposOld);
xsSrc:=xsNew;
mposNew:=0;
end else xsSrc:='';
until xsSrc = '';
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Memo1.Clear;
AddTextToMemo(',','Mr John Blue, Miss A Green, Mr Posh Hyphenated-Surname, '+
'Mr Fred Green, Miss Helen Red, Ms Jean Yellow');
end;
UPDATE
如果您有少量数据,这里快速且易于阅读。
...
var
Form1: TForm1;
NameList: TStrings;
...
NameList := TStringList.Create;
...
procedure TForm1.AddTextToMemoB(needle,xsSrc:string);
var
xsNew:string;
i:integer;
sumLen:byte;
begin
xsNew:=''; sumLen:=0;
nameList.Text:=StringReplace(xsSrc,needle,needle+#13#10,[rfReplaceAll]);
for i := 0 to nameList.Count - 1 do begin
sumLen:=SumLen+Length(nameList[i]);
if i < nameList.Count - 1 then begin
if (sumLen + Length(nameList[i+1]) > 50) then begin
if xsNew='' then xsNew:=nameList[i];
Memo1.Lines.Add(xsNew);
xsNew:='';
sumLen:=0;
end else if xsNew='' then xsNew:=nameList[i]+nameList[i+1] else
xsNew:=xsNew+nameList[i+1];
end else Memo1.Lines.Add(xsNew);
end; // for
end;
我还没有对它进行过测试,但是以下几行应该可以解决这个问题。
for LCh in S do
begin
case LCh of
',' : //Comma completes a word
begin
LWord := LWord + LCh;
if (LLine <> '') and //Don't wrap if we haven't started a line
((Length(LLine) + Length(LWord)) > ALineLimit) then
begin
//Break the current line if the new word makes it too long
AStrings.Add(LLine);
LLine := '';
end;
if (LLine <> ' ') then LLine := LLine + ' '; //One space between words
LLine := LLine + LWord;
LWord := '';
end;
else
if (LWord = '') and (LCh in [' ', #9]) then
begin
//Ignore whitespace at start of word.
//We'll explicitly add one space when needed.
//This might remove some extraneous spaces.
//Consider it a bonus feature.
end else
begin
LWord := LWord + LCh;
end;
end;
end;
//Add the remainder
if (LLine <> '') and //Don't wrap if we haven't started a line
((Length(LLine) + Length(LWord)) > ALineLimit) then
begin
//Break the current line if the new word makes it too long
AStrings.Add(LLine);
LLine := '';
end;
if (LLine <> ' ') then LLine := LLine + ' '; //One space between words
LLine := LLine + LWord;
AStrings.Add(LLine);
当然,您可能已经注意到应该移动到子例程的重复。 调整你心中的内容。