« 2007年3月 | トップページ | 2007年5月 »

☆2つのListViewを同期させる

サブアイテム数が多くて見づらいデータがあったので2つのListViewを同期させようと思い、サンプルを作ってみました。 サブクラスにはコードを見やすくするため、次のコンポーネントを使わせて頂きました。(ユニットのまま使ってるけど)

SubClassUnit
http://homepage2.nifty.com/Mr_XRAY/Halbow/Notes/N004.html

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, ExtCtrls, SubClassUnit;

type
  TForm1 = class(TForm)
    ListView1: TListView;
    ListView2: TListView;
    procedure FormCreate(Sender: TObject);
  private
    procedure SubClass1MessageAfter(Sender: TObject;
      var message: TMessage);
    procedure SubClass2MessageAfter(Sender: TObject;
      var message: TMessage);
    procedure ListView1Change(Sender: TObject; Item: TListItem;
      Change: TItemChange);
    procedure ListView2Change(Sender: TObject; Item: TListItem;
      Change: TItemChange);
  public
    SubClass1: TSubClass;
    SubClass2: TSubClass;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}


// 初期設定
procedure TForm1.FormCreate(Sender: TObject);
var
  I: Integer;
begin
  // ListView1の設定
  ListView1.ViewStyle := vsreport;
  ListView1.Columns.Add.Caption := 'ListView1';
  ListView1.Columns[0].Width := 200;
  ListView1.Height := 150;
  ListView1.HideSelection := False;

  // ListView2の設定
  ListView2.ViewStyle := vsreport;
  ListView2.Columns.Add.Caption := 'ListView2';
  ListView2.Columns[0].Width := 200;
  ListView2.Height := 150;
  ListView2.HideSelection := False;

  // テストデータの設定
  for I := 0 to 100 do
  begin
    ListView1.Items.Add.Caption := 'Item1_'+IntToStr(I);
    ListView2.Items.Add.Caption := 'Item2_'+IntToStr(I);
  end;

  // OnChangeの設定
  ListView2.Onchange := ListView2change;
  ListView1.Onchange := ListView1change;

  // サブクラスの設定
  SubClass1:= TSubClass.Create(Self);
  SubClass1.TargetControl := ListView1;
  SubClass1.OnMessageAfter := SubClass1MessageAfter;

  // サブクラスの設定
  SubClass2:= TSubClass.Create(Self);
  SubClass2.TargetControl := ListView2;
  SubClass2.OnMessageAfter := SubClass2MessageAfter;
end;

procedure TForm1.SubClass1MessageAfter(Sender: TObject;
  var message: TMessage);
var
  I, J, K: Integer;
begin
  if message.Msg = 48206  then // 48206って何?
  begin
    if (ListView1.TopItem <> nil) and (ListView2.TopItem <> nil) then
    begin
      I := ListView1.TopItem.Index;
      J := ListView2.TopItem.Index;
      K := ListView1.VisibleRowCount;
      if I <> J then
      begin
        if I > J then
          ListView2.Scroll(0, K + ABS(J-I))
        else
          ListView2.Scroll(0, (I-J)-K);
      end;
    end;
  end;
end;

procedure TForm1.SubClass2MessageAfter(Sender: TObject;
  var message: TMessage);
var
  I, J, K: Integer;
begin
  if message.Msg = 48206 then
  begin
    if (ListView1.TopItem <> nil) and (ListView2.TopItem<>nil) then
    begin
      I := ListView2.TopItem.Index;
      J := ListView1.TopItem.Index;
      K := ListView1.VisibleRowCount;
      if I <> J then
      begin
        if I > J then
          ListView1.Scroll(0, K + ABS(J-I))
        else
          ListView1.Scroll(0, (I-J)-K);
      end;
    end;
  end;
end;

procedure TForm1.ListView1Change(Sender: TObject; Item: TListItem;
  Change: TItemChange);
begin
  ListView2.OnChange := nil;
  try
    if ListView1.Selected <> nil then
      ListView2.Items[ListView1.ItemIndex].Selected := True;
  finally
    ListView2.OnChange := ListView2Change;
  end;
end;

procedure TForm1.ListView2Change(Sender: TObject; Item: TListItem;
  Change: TItemChange);
begin
  ListView1.OnChange := nil;
  try
    if ListView2.Selected <> nil then
      ListView1.Items[ListView2.ItemIndex].Selected := True;
  finally
    ListView1.OnChange := ListView1Change;
  end;
end;

end.

ソースの表示には、Hiroshi HorieさんのSource Converter1.20を使わせて頂きました。 Source Converter1.20はとても見やすいHTMLに変換してくれますので、行間が広いのは、ココログの設定のせいだと思います。→CSSを修正しました。

|

« 2007年3月 | トップページ | 2007年5月 »