2012-02-11 10 views
2

"Carbon"スタイルを使用する単純なアプリケーションをDelphi XE2で作成しています。何千もの行を持つ大きな文字列グリッドがあります。私は、このグリッドのレコードをループし、いくつかの作業を行い、グリッドにいくつかの変更を加えるプロセスを持っています。プロセスがループすると、現在処理中の行がハイライト表示されます(TStringGrid.Rowを設定します)。Delphi XE2でスタイルを使用している文字列グリッド - スクロールバーが更新されない

このグリッドにスタイルを適用すると、行が変更されてもスクロールバーの位置は変わりません。ループは処理されている間に各行を適切に強調表示しますが、リストの末尾に達するまでには、右のスクロールバーは一番上にあります。

グリッドのスクロールバーを移動するにはどうすればよいですか?

は、ここで私がループしてるかのサンプルです:私は、任意のスタイルを使用していないとき

procedure TForm1.Button1Click(Sender: TObject); 
var 
    X: Integer; 
begin 
    FStop:= False; 
    for X:= 1 to Grid.RowCount - 1 do begin 
    if FStop then Break; //Ability to stop loop 
    Grid.Row:= X; //Highlight current row 
    DoSomeLenghyWork; 
    ChangeSomethingOnGrid; 
    Application.ProcessMessages; //Keep program responding 
    end; 
end; 

すべてがうまく動作します。

Grid.Width:無効化と再描画があなたのために何もしない場合

+1

これは私にはバグのように聞こえます。 Invalidateはペイントサイクルを強制する方法です。私はバックグラウンドで処理を行い、UIを更新するためにバーチャルコントロール(例えばバーチャルモードのリストビュー)を使う傾向があると思う。タイマーでUIを更新します(例:一秒ごと。 –

+0

とにかくスレッド内の各アイテムを処理するように変換して、さまざまなイベントのメッセージを入れています。私は 'MSG_BEGIN'、' MSG_END'、 'MSG_NEXT'、' MSG_ERROR'などを持っています。 –

+0

作業を行い、メインスレッドでタイマーを実行してUIアップデートを取得するスレッドが必要です。仮想リストビューを使用して表示します。おそらくロック付きの同期化で十分です。 –

答えて

2
  1. 、文字列のグリッドリサイズしてみてください= Grid.Width - 1; Grid.Width:= Grid.Width + 1;

  2. スクロールバーを非表示にして表示する文字列グリッドオプションで試してみてください。それらを更新して後に表示する前に非表示にしてください。おそらくそれは彼らに再塗りをさせるでしょう。

  3. スクロール位置を移動して元の位置に戻すようにしてください。

+0

ありがとう、オフィスに戻ったときにやります。グリッドがalClientに揃えられているため、#1は機能しません(親の幅を変更せずに幅を変更することはできません)。それは最後の手段の迅速な修正のように思えます:P他のものは一見価値があります。 –

+0

ループ中にスクロールバーを一時的に隠してしまいました(#2)。しかし、この仕事を正しくするためのトリックがあると確信しています。 –

+0

alClient(align = alNoneとalClient)を無効にすることはできますが、それは確実にちらつきます。代わりに、常にalNoneをアライメントのままにして、代わりにアンカーを設定します。この回避策は、VCLグリッドスクロールのバグに特に役立ちます。 –

2

これは私のために働いていた - それはStringGridの境界領域を再描画するウィンドウを強制的に:

SetWindowPos(Grid.Handle, 0, 0, 0, Grid.Width, Grid.Height, SWP_DRAWFRAME); 
関連する問題