急请教——如何随意控制ListView每一行的字体的颜色——在线等候 (100分)

  • 主题发起人 主题发起人 Temp
  • 开始时间 开始时间
T

Temp

Unregistered / Unconfirmed
GUEST, unregistred user!
我在oncustomdrawitem里面改了canvas.font.color属性后发现全部行字体的颜色都
编程了这里指定的颜色,而我只想在ListView1.Items.Add.caption="xxx"这里控制
这个新加入的Items的颜色,应该如何做呢?

请诸位大侠不吝指教,谢谢!
 
1.用第三方控件(advStringGrid,TopGrid 之类的不计其数)
2.自己做:
方法1).用一个数组或者 List 纪录你需要特殊颜色的 Item 的 Index,
发现该 Item 在 List 中则换颜色,否则用缺省的画法.
方法2).类似 HTML 里标签的思路,把颜色纪录在 Item 的 caption 里,
比如,原来是 caption :='姓名',现在写成 caption := '<color=$FF0000>姓名'
这种 '<>'形式的标签(Tag) 可以在 OnCustomDrawItem 里提取出来处理,
如果没有标签则按缺省处理,
这样可能处理字符串对编程要求稍微高一点,但一劳永逸,以后还可以对付更多样化要求呢
 
密切关注
 
>>而我只想在ListView1.Items.Add.caption="xxx"这里控制这个新加入的Items的颜色,
不能在这里控制,还得在oncustomdrawitem事件里控制,只要你给出判断条件,就可以指定
不同的颜色了。
下面这一小段代码是隔行显示文字和背景的颜色,我更熟悉C++Builder,我想你应该能看明白,挺简单的
void __fastcall TForm1::ListView1CustomDrawItem(TCustomListView *Sender,
TListItem *Item, TCustomDrawState State, bool &amp;DefaultDraw)
{
if( (Item->Index%2) != 0 )
{
ListView1->Canvas->Brush->Color = TColor(0x00EEFFEE); //显示每行的背景色
Sender->Canvas->Font->Color = clRed; //显示每行的文字颜色
}
}
 
to 轻松虎大侠:

感谢你的指教,关于想法一,我想在ListView1.Items.Add.caption="xxx"添加了行后
可以通过ListView.Items.count来得到刚才添加的行的的Index,同时我通过自己的判断
决定了颜色。可是在OnCustomDrawItem里面如何控制相应Index的Item变色呢?

关于想法二,我觉得很简单可行,可是实践的时候我发现添加的标签也会显示出来阿,
可是我不想显示这个标签,请教应该如何做呢?

麻烦大侠解答,我是菜鸟,请多包涵了。

 
to sw大侠:

是这样的,我想在一个过程里决定好新增加的Items的caption和颜色(这个我已经有了语句),
然后将其写入Listview。大侠说还得在oncustomdrawitem事件里控制。可是这是一个事件阿,
可不可以在这个事件里面添加item呢?

请教~
 
to 轻松虎大侠:

我想到方法二中如何不显示Items.caption中的标签了,就是提起caption的后面几位,
可是随之而来出现了更多问题,好像问题变得很麻烦了,我在表单上面加了个listview
加了个button,主要代码如下:
-------------------
procedure TForm1.Button1Click(Sender: TObject);
begin
ListView1.Items.Add.Caption:= '1'+'hahahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakOOOOOOO';
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
ListView1.Columns[0].Width:= -1;
end;

procedure TForm1.ListView1CustomDrawItem(Sender: TCustomListView;
Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
begin
if Copy(Item.Caption,1,1)='1' then
begin
//如果第一个字符为'1'则字体为绿色
Item.Caption:= Copy(Item.Caption,2,Length(Item.Caption)-1);
listview1.Canvas.Font.Color:=clgreen;
end
else
begin

end;
end;
----------------------------------------

我在caption的前面加入一个字符,用这个字符来做关于颜色的设定,
假设'1'为绿色。发现两个问题:
1)
这个程序运行的时字体的颜色不会变化,而当注释掉
FormCreate的ListView1.Columns[0].Width:= -1;的设定后,字体才会
变色。而我又不想取消这个设置。请问这是怎么回事,应该如何解决呢?
我是W2k Server+Delphi5.0

2)当注释掉前叙语句后,发现可见字体虽然颜色变了,可是给listview的边框
遮住的部分还是黑色的,而且用鼠标点点里面的行,颜色又变成了黑白,
窗体被其他窗体遮住后也会变成默认的颜色。

其中Listview的属性如下设置:
MultiSelect:True;
ShowCloumnHeaders:False;
ViewStyle:=vsReport;


 
>>可是这是一个事件阿,可不可以在这个事件里面添加item呢?
没有必要吗!用两个事件共同显示一个Item的文字部分和颜色不凡并不复杂,也不麻烦啊!

我不太清楚你到底要实现什么功能。这样吧,如果上面我说的隔行显示不同的颜色,还有点
特殊的话,那我举一个比较随机例子。比如:我们用ListView控件显示股票的信息,就象证券
交易所里的大屏幕显示的当前股票涨跌的那个样子,每行显示一支股票的名称,开盘价......
而且,如果这支股票当前是上涨的,就用红色的文字显示;下跌就用绿色的文字显示,然后每
10秒钟刷新一次,为了及时显示当前最新的涨跌情况(哈哈,我对股票不是很懂,说出外行话
大家不要笑话我啊 :-)
假如显示的顺序是下面这样的:
===========================================
股票名称 开盘价 当前价 ......
-------------------------------------------
四川长虹 1111 2322 ......
炎黄在线 1212 3333 ......
.............................
.............................
===========================================

那么就应该这样做:

void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
//每隔10秒钟从接收装置中取来最新的数据,更新一次ListView
TListItem* NewItem ;
ListView1->Items->BeginUpdate(); //禁止ListView控件刷新
ListView1->Items->Clear();
for(int i=0; i<股票一共有多少支; i++) //用一个循环将股票数据的文字部分更新一遍
{
NewItem = ListView1->Items->Add();
NewItem->Caption = "股票名称";
NewItem->SubItems->Add( "开盘价" );
NewItem->SubItems->Add( "当前价" );
......
}
ListView1->Items->EndUpdate();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ListView1CustomDrawItem(TCustomListView *Sender,
TListItem *Item, TCustomDrawState State, bool &amp;DefaultDraw)
{
//在这里指定颜色,假设你用数据库存取历史记录,就应该用最新收到的“当前价”和
//上一次的“当前价”相比较,这样,就知道股票的涨跌情况了,就利用这一点来指定
//相应的显示颜色

if( StrToInt(Item->SubItems->Strings[1]) > "31" )
Sender->Canvas->Font->Color = clRed;
else
Sender->Canvas->Font->Color = clGreen;
// StrToInt(Item->SubItems->Strings[1]) 是将最新的“当前价”转换为整型
// "31" 假设是上一次的“当前价”

}

这样不就行了吗,就是判断一下,也并不麻烦呀
 
to Sw大侠:

非常你的解答!提出了另外一种思路。

我得问题已经基本解决了,只有一个小小问题。请看我得源程序。我在表单上面放置了两个button和一个listview
按下button1则增加一行绿色的item,按下button2则增加一行红色的item。
源代码如下,麻烦大侠过目:
--------------------------------------
unit F_Main;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls, Menus;

type
TForm1 = class(TForm)
ListView1: TListView;
Button1: TButton;
PopupMenu1: TPopupMenu;
SelectAll1: TMenuItem;
Clear1: TMenuItem;
Clear2: TMenuItem;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure ListView1CustomDrawItem(Sender: TCustomListView;
Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
ChangeColor: array of integer;
//用于记录相应Item颜色的动态数组

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
// ListView1.Columns[0].Width:= -1;
ListView1.Columns[0].Width:=ListView1.Width-8;
end;

procedure TForm1.Button1Click(Sender: TObject);
//设button1添加绿色的Item
begin
ListView1.Items.Add.Caption:= 'Greennnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn';
//增加的Items,并指定其caption属性
ListView1.Items[ListView1.Items.Count-1].Selected;
//将新增加的Item设为selected
SetLength(ChangeColor,High(ChangeColor)+2);
//为动态数组增配空间
ChangeColor[High(ChangeColor)]:=1;
//设置颜色代码,1为绿色
end;

procedure TForm1.Button2Click(Sender: TObject);
//设button2添加红色的Item
begin
ListView1.Items.Add.Caption:= 'Reddddddddddddddddddddddddddddddddddddddddddddddddddddddd';
ListView1.Items[ListView1.Items.Count-1].Selected;
SetLength(ChangeColor,High(ChangeColor)+2);
ChangeColor[High(ChangeColor)]:=2;
end;

procedure TForm1.ListView1CustomDrawItem(Sender: TCustomListView;
Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
begin
if ChangeColor[Item.Index]=1 then
begin
listview1.Canvas.Font.Color:=clgreen;
end else if ChangeColor[Item.Index]=2 then
begin
listview1.Canvas.Font.Color:=clRed;
end;
end;

end.
----------------------------------

这个程序运行起来没有问题,可是注意到我把FormCreate过程里面的
ListView1.Columns[0].Width:= -1;语句给注释掉了,而使用
ListView1.Columns[0].Width:=ListView1.Width-8;来勉强替代,
这并不是我得本意,我得本意是想使用ListView1.Columns[0].Width:= -1;
但是只要使用这个语句,运行后按button时就会出现Read of Address"xxxxx"之类的
错误,我百思不得其解,请大侠指教。
 
多谢两位大侠的帮助
 
后退
顶部