2017-08-06 35 views
0

我是新的TAniindicator組件,因此出於測試目的,我已經將一個項目放在一起,這個項目將構建listview並在listview構建時顯示/旋轉Aniicicator。TAniIndicator不旋轉 - 加載tlistview

type 
TLoadThread = class(TThread) 
public 
constructor Create; reintroduce; 
protected 
procedure Process; 
procedure Execute; override; 
end;  

constructor TLoadThread.Create; 
begin 
inherited Create(True); 
FreeOnTerminate := True; 
end; 

procedure TLoadThread.Process; 
begin 
Form1.BuildListView; 
end; 

procedure TLoadThread.Execute; 
begin 
inherited; 
FreeOnTerminate := True; 
Synchronize(Process); 
end; 

var _loadThread : TLoadThread; 

procedure TForm1.ThreadTerminated(Sender: TObject); 
begin 
AniIndicator1.Enabled := False; 
AniIndicator1.Visible := False; 
end; 

procedure TForm1.BuildListView; 
var i : integer; 
    LI : TListViewItem; 
begin 
    Listview1.BeginUpdate; 
try 
    for i := 1 to 2000 do 
    begin 
    LI := Listview1.Items.Add; 
    LI.Text := 'Listview Item ' + IntToStr(i); 
    end; 
finally 
    Listview1.EndUpdate; 
end; 
end; 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
AniIndicator1.Visible := False; 
_loadThread := nil; 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
begin 
_loadThread := TLoadThread.Create; 
_loadThread.OnTerminate := ThreadTerminated; 
_loadThread.Start; 
AniIndicator1.Enabled := True; 
end; 

我以爲我是在正確的軌道上,但是這似乎並沒有工作,任何人都可以解釋我做錯了什麼嗎?

回答

0

您的工作線程將其所有時間花費在Process()方法中,該方法由TThread.Synchronize()調用,因此它在主UI線程中運行。 Process()未處理UI消息,這就是爲什麼TAniIndicator不起作用。

原來,你的工作線程是完全沒用的。所有的代碼都在主UI線程中運行。所以,你不妨擺脫TLoadThread乾脆:

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    AniIndicator1.Visible := False; 
end; 

procedure TForm1.BuildListView; 
var 
    i : integer; 
    LI : TListViewItem; 
begin 
    AniIndicator1.Visible := True; 
    AniIndicator1.Enabled := True; 
    ListView1.BeginUpdate; 
    try 
    for i := 1 to 2000 do 
    begin 
     LI := ListView1.Items.Add; 
     LI.Text := 'ListView Item ' + IntToStr(i); 
     if (i mod 100) = 0 then 
     Application.ProcessMessages; 
    end; 
    finally 
    ListView1.EndUpdate; 
    AniIndicator1.Enabled := False; 
    AniIndicator1.Visible := False; 
    end; 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
begin 
    BuildListView; 
end; 

否則,如果你使用一個線程,不同步的循環本身,只有片實際觸摸UI:

type 
    TLoadThread = class(TThread) 
    public 
    constructor Create; reintroduce; 
    protected 
    procedure Execute; override; 
    end; 

constructor TLoadThread.Create; 
begin 
    inherited Create(True); 
    FreeOnTerminate := True; 
end; 

procedure TLoadThread.Execute; 
begin 
    Form1.BuildListView; 
end; 

var 
    _loadThread : TLoadThread = nil; 

procedure TForm1.ThreadTerminated(Sender: TObject); 
begin 
    _loadThread := nil; 
end; 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    AniIndicator1.Visible := False; 
end; 

procedure TForm1.BuildListView; 
var 
    i : integer; 
begin 
    TThread.Synchronize(nil, 
    procedure 
    begin 
    AniIndicator1.Visible := True; 
    AniIndicator1.Enabled := True; 
    ListView1.BeginUpdate; 
    end 
); 
    try 
    for i := 1 to 2000 do 
    begin 
     TThread.Synchronize(nil, 
     procedure 
     var 
      LI : TListViewItem; 
     begin 
      LI := ListView1.Items.Add; 
      LI.Text := 'ListView Item ' + IntToStr(i); 
     end 
    ); 
    end; 
    finally 
    TThread.Synchronize(nil, 
     procedure 
     begin 
     ListView1.EndUpdate; 
     AniIndicator1.Enabled := False; 
     AniIndicator1.Visible := False; 
     end 
    ); 
    end; 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
begin 
    if _loadThread <> nil then 
    begin 
    _loadThread := TLoadThread.Create; 
    _loadThread.OnTerminate := ThreadTerminated; 
    _loadThread.Start; 
    end; 
end; 
+0

雷米,非常感謝你的投入,現在它變得更有意義,非常感謝:) –