2

TListview我正在尝试在具有他的属性的项目的左侧显示负数的减号BiDiMode = bdRightToLeft.

我在那里尝试了代码:

DBGrid 中的千位分隔符

Function TfrmProjets.IfSign(floatValue: double; howMuchDecimalAfterComa: 

integer):string;
var
  strResult: string;
  strZero: string;
  i: integer;
begin
  strResult := '';
  strZero := '';

  for i := 0 to howMuchDecimalAfterComa -1 do
  begin
    strZero := strZero + '0';
  end;

  if(Sign(floatValue) = NegativeValue)then
  begin
      strResult := '-' + FormatFloat('0.' + strZero,Abs(floatValue));
    //strResult := '(' + FormatFloat('0.' + strZero,Abs(floatValue)) + ')';
  end
  else
  begin
    strResult := FormatFloat('0.' + strZero,floatValue);
  end;

  result := strResult;
end;

事实上,当我使用断点进行评估时它会起作用strResult

但是当它TListView显示在我的项目中时:

lvItem := lvPeriodic[0];
lvItem.SubItems.Add(IfSign(-14.2),1) + '%') ;

它显示如下:14.2%-

有没有办法告诉TListview不要更改我正在显示的字符串或其他东西?

4

1 回答 1

4

假设您使用的是 unicode 版本的 delphi,您可以提供显式 RTL 和 LTR 标记来强制语言中性或弱字符(如 dash -、 exclamation!等)的位置。

在各种上下文中解析 LTR 和 RTL 文本的规则是广泛而复杂的。作为参考,您可以在此处找到双向算法规范。弱字符的一次传递确实将欧洲数字解析为 LTR(这就是为什么14.2%最终以正确的方向结束,但使用破折号-表示减号会引入歧义。有人会认为替换正确的减号U+2212会起作用,但这也是弱字符,大概是因为阿拉伯数字也可以是负数(并且需要以相反的方向呈现......我不确定)。

在任何情况下 - 继续前进,我们可以构造一个这样的函数来强制字符串进入严格的 LTR 顺序:

function StrictLTR(const s : string) : string;
const
  LTR_EMBED = Char($202A);
  POP_DIRECTIONAL = Char($202C);
begin
  result := LTR_EMBED + s + POP_DIRECTIONAL;
end;

这会在字符串之前放置一个嵌入的从左到右字符 ( U+202A),并在其后跟一个 Pop-Directional-Formatting ( U+202C) 字符。后者删除嵌入的方向格式提示并将文本方向返回到之前上下文中的任何内容。因此,返回的字符串在 RTL 或 LTR 上下文中使用都是安全的。

调用这个,然后:

 ListView1.AddItem(StrictLTR(IfSign(-14.2,1) + '%'), nil);

会产生想要的结果。


顺便说一句,您的IfSign功能可以通过使用以下Format功能大大简化:

Function IfSign(floatValue: double; numberOfDecimalPlaces:integer):string;
begin
  result := Format('%.'+IntTostr(numberOfDecimalPlaces)+'f', [floatValue]);
end;
于 2015-11-03T19:50:55.087 回答