![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Помогите настроить отображение массива в TListView?
Пироги © (2011-01-29 19:01:00)Задача отображать массив в TListView в режиме OnOwnerDraw.
Делаю так:
Unit1.pas
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, ExtCtrls;
type
TForm1 = class(TForm)
ListView1: TListView;
CheckBox1: TCheckBox;
CheckBox2: TCheckBox;
CheckBox3: TCheckBox;
Button1: TButton;
CheckBox4: TCheckBox;
CheckBox5: TCheckBox;
Button3: TButton;
Label2: TLabel;
procedure ListView1DrawItem(Sender: TCustomListView; Item: TListItem;
Rect: TRect; State: TOwnerDrawState);
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure ListView1Change(Sender: TObject; Item: TListItem;
Change: TItemChange);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
const
Count1 = 5;
{$R *.dfm}
function InRange(const AValue, AMin, AMax: Integer): Boolean;
begin
Result := (AValue >= AMin) and (AValue
FlatScrollBars = True
MultiSelect = True
OwnerData = True
OwnerDraw = True
ReadOnly = True
RowSelect = True
TabOrder = 0
ViewStyle = vsReport
OnChange = ListView1Change
OnDrawItem = ListView1DrawItem
end
object CheckBox1: TCheckBox
Left = 144
Top = 56
Width = 97
Height = 17
Caption = 'CheckBox1'
TabOrder = 1
end
object CheckBox2: TCheckBox
Left = 144
Top = 80
Width = 97
Height = 17
Caption = 'CheckBox2'
TabOrder = 2
end
object CheckBox3: TCheckBox
Left = 144
Top = 104
Width = 97
Height = 17
Caption = 'CheckBox3'
TabOrder = 3
end
object Button1: TButton
Left = 136
Top = 8
Width = 75
Height = 25
Caption = 'Invalidate'
TabOrder = 4
OnClick = Button1Click
end
object CheckBox4: TCheckBox
Left = 144
Top = 128
Width = 97
Height = 17
Caption = 'CheckBox4'
TabOrder = 5
end
object CheckBox5: TCheckBox
Left = 144
Top = 152
Width = 97
Height = 17
Caption = 'CheckBox5'
TabOrder = 6
end
object Button3: TButton
Left = 232
Top = 8
Width = 75
Height = 25
Caption = 'Item index'
TabOrder = 7
end
end
Вместо массива здесь используются чекбоксы, просто для отладки.
Вроде бы всё в порядке, может выбирать строчки в ListView, и чекбоксы выставляются в соответствии с выбором, и наоборот, можно выставить чек-боксы в нужные значения, потом нажать на кнопку Invalidate и строчки в ListView выбирутся в соответствии с чекбоксами.
Но оказалось, есть случаи когда это не срабатывает. Например.
Выбираем в ListView элемент 2, нажимаем Shift и выбираем элемент 4. У нас выделяются 3 элемента и 3 чекбокса соответствующие им. Теперь отключаем CheckBox2 и нажимаем на Invalidate, теперь в ListView выбрано только два элемента. Всё правильно. Дальше жмём на Ctrl и жмём на четвёртый элемент. В результате у нас должен был бы остаться выделенным только третий элемент, а вместо этого их остаётся выделенными два, второй и третий и чек-боксов тоже выделено два.
Как исправить код, чтобы этого глюка не возникало?
sniknik (2011-03-10 22:10:00) [1]> То есть как работать с событие OnData вы не знаете.
да че там учится то? наливай да пей!
был бы OnData в исходном, кривом коде исправил бы и с ним. а так... "я его слепила из того, что было".
> Потому, что кому нужны советы от того, кто ничего не знает.
тому кто знает еще меньше. если он конечно хочет учится... а тебе бы пора научится тому, что переменные нужно инициализировать перед использованием... или не использовать.
KilkennyCat (2011-03-10 21:33:00) [2]
> событие OnData
че-то не видать его в коде.
Пироги (2011-03-10 20:43:00) [3]
> sniknik © (03.02.11 19:29) [11]
>
> > Скажите, если у вас миллион значений, то вы так и будете
> каждый раз засандаливать в миллион Items их значения Selected
> ?
> у меня такого бреда не бывает, пример вообще то твой, я
> только исправил...
> и да, придется таки "засандаливать" пока в другой части
> кода значения этих переменных используются.
То есть как работать с событие OnData вы не знаете. Понятно.
Так бы сразу и сказали.
Прежде чем советовать лучше сначала научиться. Потому, что кому нужны советы от того, кто ничего не знает. Верно?
sniknik (2011-02-03 19:29:00) [4]> Скажите, если у вас миллион значений, то вы так и будете каждый раз засандаливать в миллион Items их значения Selected ?
у меня такого бреда не бывает, пример вообще то твой, я только исправил...
и да, придется таки "засандаливать" пока в другой части кода значения этих переменных используются.
> Вместо того, чтобы обновить только отображаемые на экране элементы ListView.
флаг в руки, считаешь что знаешь лучше всех? тогда не спрашивай. делай!
но пока твои измышления не работают - учись.
Пироги (2011-02-03 17:56:00) [5]
> sniknik © (29.01.11 20:12) [1]
> Items[0].Selected:= CheckBox1.Checked;
> Items[1].Selected:= CheckBox2.Checked;
> Items[2].Selected:= CheckBox3.Checked;
> Items[3].Selected:= CheckBox4.Checked;
> Items[4].Selected:= CheckBox5.Checked;
Скажите, если у вас миллион значений, то вы так и будете каждый раз засандаливать в миллион Items их значения Selected ? Вместо того, чтобы обновить только отображаемые на экране элементы ListView.
> Andy BitOff © (29.01.11 21:23) [6]
> фига, какая наглая школота поперла
Действительно.
Inovet (2011-01-29 22:13:00) [6]> [3] Пироги (29.01.11 20:36)
> Я не спрашивал во что мне переименовать itInd , я спросил
> как решить проблему.
Вумный вьюнош? Так зачем сюдв тогда пожаловал? Кстати, i в данном случае понятнее чем itInd, так что учись у тех, кто не первый день, год и даже не перый, о ужас, десяток лет этим занимается. Впрочем, советы по альтернативным видам деятельности тебе тоже дали на твоё же благо.
sniknik (2011-01-29 21:28:00) [7]> фига, какая наглая школота поперла
ну так, он же сюда не учится пришел, а ему тут вдруг код на понимание процесса дали, а не для копи пасте...
sniknik (2011-01-29 21:26:00) [8]> Мне не нужен CheckBoxClick
мало ли, что тебе не нужно... в примере он более показателен. а если не можешь понять смысл действий, только из-за смены компонента/события... это твои проблемы. или программирование это не твое.
Andy BitOff (2011-01-29 21:23:00) [9]фига, какая наглая школота поперла
sniknik (2011-01-29 21:20:00) [10]> я спросил как решить проблему.
на это отвечено. прямым текстом. + код расширен, с половинчатого, до более универсального примера. но...
не доходят сообщения? попробуйте перечитать их еще раз...
не доходит после повторного? смени занятие на что попроще, с метлой например потренируйся. вдруг хоть это получится.
KilkennyCat (2011-01-29 21:05:00) [11]
> sniknik ©
спасибо.
это я тебе вместо него сказал, оценив проделанный труд.
Пироги (2011-01-29 20:36:00) [12]
> procedure TForm1.CheckBoxClick(Sender: TObject);
Мне не нужен CheckBoxClick, у меня нет никаких чекбоксов, есть массив. Чекбоксы введены временно, только для отловли этого глюка.
> var
> i: integer;
> i:= Item.Index;
Зачем менять itInd на ничего не значащее i ? Я не спрашивал во что мне переименовать itInd , я спросил как решить проблему.
sniknik (2011-01-29 20:16:00) [13]
procedure TForm1.ListView1DrawItem(Sender: TCustomListView; Item: TListItem; Rect: TRect; State: TOwnerDrawState);
var
i: integer;
b: Boolean;
begin
i:= Item.Index;
case i of
0: b:= CheckBox1.Checked;
1: b:= CheckBox2.Checked;
2: b:= CheckBox3.Checked;
3: b:= CheckBox4.Checked;
4: b:= CheckBox5.Checked;
end;
with Sender.Canvas do begin
if b then begin
Brush.Color:= clGreen;
Font.Color := clWhite;
end else
Brush.Color:= clWhite;
TextRect(Rect, 2 , Rect.Top, '( '+IntToStr(i+1)+' ) '+IntToStr(Byte(b)));
if odFocused in State then begin
if b then Pen.Color:= clWhite
else Pen.Color:= clBlack;
Brush.Style:= bsClear;
Rectangle(Rect.Left+1, Rect.Top+1, Rect.Right-1, Rect.Bottom -1);
end;
end;
end;
sniknik (2011-01-29 20:12:00) [14]> Как исправить код, чтобы этого глюка не возникало?
меняешь что то, следи чтобы это не вызывало событие "обратного изменения"
ну и Invalidate не устанавливает Selected.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, ExtCtrls;
type
TForm1 = class(TForm)
ListView1: TListView;
CheckBox1: TCheckBox;
CheckBox2: TCheckBox;
CheckBox3: TCheckBox;
CheckBox4: TCheckBox;
CheckBox5: TCheckBox;
procedure ListView1DrawItem(Sender: TCustomListView; Item: TListItem; Rect: TRect; State: TOwnerDrawState);
procedure ListView1Change(Sender: TObject; Item: TListItem; Change: TItemChange);
procedure CheckBoxClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
Auto: boolean;
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.ListView1DrawItem(Sender: TCustomListView; Item: TListItem; Rect: TRect; State: TOwnerDrawState);
var
i: integer;
b: Boolean;
begin
i:= Item.Index;
case i of
0: b:= CheckBox1.Checked;
1: b:= CheckBox2.Checked;
2: b:= CheckBox3.Checked;
3: b:= CheckBox4.Checked;
4: b:= CheckBox5.Checked;
end;
with Sender do begin
if b then begin
Canvas.Brush.Color:= clGreen;
Canvas.Font.Color := clWhite;
end else
Canvas.Brush.Color:= clWhite;
Canvas.TextRect(Rect, 2 , Rect.Top, '( '+IntToStr(i+1)+' ) '+IntToStr(Byte(b)));
if odFocused in State then begin
Canvas.Pen.Color := clWhite;
Canvas.Brush.Style:= bsClear;
Canvas.Rectangle(Rect.Left+1, Rect.Top+1, Rect.Right-1, Rect.Bottom -1);
end;
end;
end;
procedure TForm1.ListView1Change(Sender: TObject; Item: TListItem; Change: TItemChange);
begin
Auto:= true;
with ListView1 do
try
CheckBox1.Checked:= Items[0].Selected;
CheckBox2.Checked:= Items[1].Selected;
CheckBox3.Checked:= Items[2].Selected;
CheckBox4.Checked:= Items[3].Selected;
CheckBox5.Checked:= Items[4].Selected;
finally
Auto:= false;
end;
end;
procedure TForm1.CheckBoxClick(Sender: TObject);
begin
if Auto then Exit;
with ListView1 do begin
OnChange:= nil;
try
Items[0].Selected:= CheckBox1.Checked;
Items[1].Selected:= CheckBox2.Checked;
Items[2].Selected:= CheckBox3.Checked;
Items[3].Selected:= CheckBox4.Checked;
Items[4].Selected:= CheckBox5.Checked;
finally
OnChange:= ListView1Change;
end;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
ListView1.Items.Count:= 5;
Auto:= false;
end;
end.
object Form1: TForm1
Left = 279
Top = 113
Width = 401
Height = 304
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
PixelsPerInch = 96
TextHeight = 13
object ListView1: TListView
Left = 0
Top = 0
Width = 121
Height = 277
Align = alLeft
Columns = <
item
end>
FlatScrollBars = True
MultiSelect = True
OwnerData = True
OwnerDraw = True
ReadOnly = True
RowSelect = True
TabOrder = 0
ViewStyle = vsReport
OnChange = ListView1Change
OnDrawItem = ListView1DrawItem
end
object CheckBox1: TCheckBox
Left = 152
Top = 8
Width = 97
Height = 17
Caption = 'CheckBox1'
TabOrder = 1
OnClick = CheckBoxClick
end
object CheckBox2: TCheckBox
Left = 152
Top = 32
Width = 97
Height = 17
Caption = 'CheckBox2'
TabOrder = 2
OnClick = CheckBoxClick
end
object CheckBox3: TCheckBox
Left = 152
Top = 56
Width = 97
Height = 17
Caption = 'CheckBox3'
TabOrder = 3
OnClick = CheckBoxClick
end
object CheckBox4: TCheckBox
Left = 152
Top = 80
Width = 97
Height = 17
Caption = 'CheckBox4'
TabOrder = 4
OnClick = CheckBoxClick
end
object CheckBox5: TCheckBox
Left = 152
Top = 104
Width = 97
Height = 17
Caption = 'CheckBox5'
TabOrder = 5
OnClick = CheckBoxClick
end
end