2015-10-05 31 views
0

我有一個問題,如果我得到我定義的類型對象。 我需要從ListBox中獲取我的變量定義的對象。TCheckListBox獲取我的對象

我的數據類型:

type 
    TObjectData = class 
    Id: Integer; 
    DataType: String; 
    end; 
    TProjektInfo = record 
    Id: Integer; 
    Nazev: String; 
    end; 
    TReportSelect = record 
    Count: Integer; 
    Zakazka_Id: Integer; 
    Singles: Array of TProjektInfo; 
    Multies: Array of TProjektInfo; 
    end; 

我對填充列表框過程:

procedure TReportMain.VykresyFillProjectsList(); 
var 
    I,Id: Integer; 
    Nazev: String; 
    ItemData: TObjectData; 
begin 
    VykresyProjectsListSections.Items.BeginUpdate; 
    VykresyProjectsListSections.Items.Clear; 

    for I := Low(ReportSelect.Singles) to High(ReportSelect.Singles) do 
    begin 

    Id := ReportSelect.Singles[I].Id; 
    Nazev := ReportSelect.Singles[I].Nazev; 

    ItemData := TObjectData.Create; 
    ItemData.Id := Id; 
    ItemData.DataType := 'single'; 

    VykresyProjectsListSections.Items.AddObject(Nazev, TObject(ItemData)); 
    ItemData.Free; 
    end; 

    for I := Low(ReportSelect.Multies) to High(ReportSelect.Multies) do 
    begin 

    Id := ReportSelect.Multies[I].Id; 
    Nazev := ReportSelect.Multies[I].Nazev; 

    ItemData := TObjectData.Create; 
    ItemData.Id := Id; 
    ItemData.DataType := 'multi'; 

    VykresyProjectsListSections.Items.AddObject(Nazev, TObject(ItemData)); 
    ItemData.Free; 
    end; 

    VykresyProjectsListSections.Items.EndUpdate; 
end; 

上點擊讓我的數據類型的對象我的按鈕事件(這是錯在何處被註釋掉):

procedure TReportMain.BtnExportProjectsClick(Sender: TObject); 
var 
    ItemData: TObjectData; 
    Nazev: String; 
    I: Integer; 
begin 
    ItemData := TObjectData.Create; 

    for I := 0 to VykresyProjectsListSections.Count - 1 do 
    begin 

    if VykresyProjectsListSections.Checked[I] then 
    begin 

     ItemData := TObjectData(VykresyProjectsListSections.Items.Objects[I]); // <--- This is wrong, why ? 
     Nazev := VykresyProjectsListSections.Items.Strings[I]; 

     showMessage(Format('Nazev: %s ID: %d Type: %s', [Nazev, ItemData.Id, ItemData.DataType])); 

    end; 

    end; 
end; 
+0

你說這是錯的,但不是爲什麼它是錯的。請解釋。我們也不知道你的目標是什麼平臺,以及弧是否激活。 –

+0

評註顯示訪問衝突。 Line:ItemData:= TObjectData(VykresyProjectsListSections.Items.Objects [I]); ,我不知道爲什麼。 –

+0

如果您提供了我要求的其他詳細信息,這將有所幫助。並且在問題**編輯**而不是在評論中這樣做。 –

回答

2

發生在你身上什麼可能是一個訪問衝突

你要訪問的變量是不確定的,因爲你已經釋放了變量指向的對象。

在上面的代碼,它添加到列表中後ItemData對象總是被釋放。

您必須編寫一些代碼來清除或釋放列表時釋放對象。

這可以在OnDestroy事件的形式來完成:

procedure TReportMain.FormDestroy(Sender: TObject); 
var 
    i: Integer; 
begin 
    for i := VykresyProjectsListSections.Items.Count-1 downto 0 do begin 
    VykresyProjectsListSections.Items.Objects[i].Free; 
    VykresyProjectsListSections.Delete(i); 
    end; 

    VykresyProjectsListSections.Free;//free the list if not owned by the application 
end; 

作爲一個側面說明,您可以測試是否TCheckListBox元素被選中是這樣的:

var 
    i: Integer; 
begin 
    for i := 0 to VykresyProjectsListSections.Items.Count-1 do begin 
    if VykresyProjectsListSections.State[i] = cbChecked then 
     //do your stuff 
    end; 
end; 
+0

然而,這並沒有解決我的情況。我需要讓列表中的對象被檢查。 –

+0

@LukášVlček這是一個你沒問的問題。以上可能不能解決許多其他情況。目前我甚至不知道什麼樣的組件'VykresyProjectsListSections'。如果需要,您可以考慮編輯您的問題以添加更多詳細信息。 – fantaghirocco

+0

你的回答幫了我。我明白,如果我想使用它,我無法發佈該對象。謝謝 –

0

您在AddObject()之後致電ItemData.Free。這是錯誤的,因爲對象將不再有效。

這將導致錯誤時以後訪問所述CheckListBox的對象。

+0

但是,如果我們使用ARC,我想 –

+0

@DavidHeffernan,即使是這樣,它仍然不是一個好習慣。 –

+0

我不同意這一點。我只希望提問者會更關心這個問題。 –