2013-04-22 58 views
1

基本上我想有一個StringList的填充的ListView控件,當我選擇列表項,並按向上或向下移動時的項目向上或向下(在這兩個列表)。的ListView不選擇正確的行

我使用ListView的的onkeydown調用MoverFAT

procedure TF_Aplicador.ListViewKeyDown(Sender: TObject; var Key: Word; 
    Shift: TShiftState); 
begin 
    if ListView.Selected <> nil then 
    if Key = VK_UP then 
     MoverFAT(ListView.Selected.Index, -1) 
    else if Key = VK_DOWN then 
     MoverFAT(ListView.Selected.Index, 1) 
    else if Key = VK_DELETE then 
     DeletarFAT(ListView.Selected.Index); 
end; 

而且問題是向下移動時,它總是選擇第一項(交換損益後),並連升作品就好了。 FAT是我的StringList,Atualizar()只是讓ListView顯示StringList的內容。

ListView.Clear; 
    for I := 0 to FATs.Count - 1 do 
    ListView.AddItem(FATs[I], nil); 

(它肯定會一直是容易得多,如果你給了我們,太)

的問題是:

procedure TF_Aplicador.MoverFAT(I, J: Integer); 
begin 
    if ((I + J) > -1) and ((I + J) < (FATs.Count)) then 
    begin 
    FATs.Exchange(I, I+J); 
    Atualizar; 
    ListView.Selected := ListView.Items[I+J]; 
    end; 
end; 
+1

我無法重現那樣的問題。我正在使用過程TForm6.ListViewData(發件人:TObject;項目:TListItem); 開始 Item.Caption:= FATs [Item.Index]; 結束;與OwnerData =真 – bummi 2013-04-22 18:19:22

回答

3

我用下面的Atualizer實現轉載您的問題ListView本身會嘗試處理密鑰,但由於您(可能)刪除了Atualizer例程中的所有項目,因此它不知道如何操作。

由分配0再告訴它不應該處理的關鍵筆劃ListView控件解決它:

procedure TF_Aplicador.ListViewKeyDown(Sender: TObject; var Key: Word; 
    Shift: TShiftState); 
begin 
    if ListView.Selected <> nil then 
    begin 
    case Key of 
     VK_UP: MoverFAT(ListView.ItemIndex, -1); 
     VK_DOWN: MoverFAT(ListView.ItemIndex, 1); 
     VK_DELETE: DeletarFAT(ListView.ItemIndex); 
    end; 
    if Key in [VK_UP, VK_DOWN, VK_DELETE] then 
     Key := 0; 
    end; 
end; 

補充說明:對於同步的StringList和ListView的更好的方法。您可以使用Bummi's comment的虛擬方法。或者你可以交換ListView的項目過多,在這種情況下,你不需要再壓抑的關鍵:

procedure TForm1.ListViewKeyDown(Sender: TObject; var Key: Word; 
    Shift: TShiftState); 
begin 
    if ListView.Selected <> nil then 
    case Key of 
     VK_UP: MoverFAT(ListView.ItemIndex, -1); 
     VK_DOWN: MoverFAT(ListView.ItemIndex, 1); 
     VK_DELETE: DeletarFAT(ListView.ItemIndex); 
    end; 
end; 

procedure ExchangeListItems(Items: TListItems; Index1, Index2: Integer); 
var 
    Item: TListItem; 
begin 
    Item := TListItem.Create(Items); 
    try 
    Item.Assign(Items[Index1]); 
    Items[Index1].Assign(Items[Index2]); 
    Items[Index2].Assign(Item); 
    finally 
    Item.Free; 
    end; 
end; 

procedure TForm1.MoverFAT(I, J: Integer); 
begin 
    if ((I + J) > -1) and ((I + J) < (FATs.Count)) then 
    begin 
    FATs.Exchange(I, I + J); 
    ExchangeListItems(ListView.Items, I, I + J); 
    end; 
end; 
+0

+1尋找什麼我忘了搜索8-( – bummi 2013-04-22 18:36:04

+0

好,雖然Bummi的評論確實是這樣做的更好的方法,你是簡單了很多:)我還需要學習如何處理這些處理。 – 2013-04-22 20:08:48

2

儘可能NGLN已經指出的問題,我建議另一種方法。
不要在Listview中存儲數據,只是用它來顯示數據。 只需要一個未觸動的列表視圖和列表框進行演示。

unit Unit6; 

interface 

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

type 
    TForm6 = class(TForm) 
    ListView: TListView; 
    ListBox1: TListBox; // just for visualization should be an Stringlist 
    procedure ListViewKeyDown(Sender: TObject; var Key: Word; 
     Shift: TShiftState); 
    procedure FormCreate(Sender: TObject); 
    procedure ListViewData(Sender: TObject; Item: TListItem); 
    private 
    procedure MoverFAT(I, J: Integer); 
    { Private-Deklarationen } 
    public 
    { Public-Deklarationen } 
    end; 

var 
    Form6: TForm6; 

implementation 

var 
    FATs: TStrings; 
{$R *.dfm} 

procedure TForm6.FormCreate(Sender: TObject); 
var 
    I: Integer; 
begin 
    for I := 0 to 9 do 
    ListBox1.Items.Add(StringOfChar(IntToStr(I)[1], 10)); 
    ListView.Columns.Add.Caption := 'Test'; 
    ListView.ViewStyle := vsList; 
    ListView.OwnerData := true; 
    ListView.OnData := ListViewData; 
    Listview.OnKeyDown := ListViewKeyDown; 
    FATs := ListBox1.Items; 
    ListView.Items.Count := FATs.Count; 
end; 

procedure TForm6.ListViewData(Sender: TObject; Item: TListItem); 
begin 
    Item.Caption := FATs[Item.Index]; 
end; 

procedure TForm6.ListViewKeyDown(Sender: TObject; var Key: Word; 
    Shift: TShiftState); 
begin 
    if ListView.Selected <> nil then 
    if Key = VK_UP then 
     MoverFAT(ListView.Selected.Index, -1) 
    else if Key = VK_DOWN then 
     MoverFAT(ListView.Selected.Index, 1) 
end; 

procedure TForm6.MoverFAT(I, J: Integer); 
begin 
    if ((I + J) > -1) and ((I + J) < (FATs.Count)) then 
    begin 
    FATs.Exchange(I, I + J); 
    ListView.Invalidate; 
    ListView.Selected := ListView.Items[I + J]; 
    end; 
end; 

end. 
+0

我只是使用ListView來顯示數據。 NGLN與我的問題一樣,但非常感謝您的幫助! – 2013-04-22 20:05:32