2016-12-19 1 views
0

몇 가지 사용자 지정 열거 자 세트를 만들었습니다.Delphi - 열거 자 유형의 항목을 ComboBox에 바인딩하고 선택한 항목을 객체에 바인딩하는 방법

예 :

Type TStatus=(Unknown=0, Dead=1, Owned=2, Borrowed=3); 

지금 내 설정에 정의 된 모든 항목으로 콤보 상자를 채우기 위해 싶어요. 그래서 내 주먹 생각 TypeInfo, GetEnumName 및 GetEnumValue 함수를 사용하는 것입니다.

i:=0; 
while GetEnumValue(TypeInfo(TStatus),GetEnumName(TypeInfo(TStatus),i))<>-1 do 
begin 
    status:=GetEnumName(TypeInfo(TStatus),i); 
    ComboBox.Items.Add(status); 

    inc(i); 
end; 

(나는 별도의 어댑터로 ComboBox에 TStringList를 바인딩하려했지만 작동하지 않았습니다.)

내 ComboBox를 채운 후 LiveBindings를 사용하여 상태가 간단히 불리는 내 개체의 TStatus- 속성에 "SelectedValue"속성을 바인딩했습니다.

세 가지 문제점이 있습니다.

  1. Status-property에 기본값을 할당 했는데도 개체를 스크롤 할 때 Combobox에 아무 값도 표시되지 않습니다.

  2. 콤보 상자에있는 항목의 금액은 다음과 같습니다

    Amount of Items in Set + Amount of Objects 
    

    내가 내 콤보 상자에서 6 개 항목이 2 개체가 있다면이 값을 선택하면 그래서 때 4

  3. 유지한다 콤보 박스에서 그것을 내 개체에 게시하고 싶습니다. 내 Setter-Function에 액세스하지 못합니다.

이 라이브 바인딩은 전체적으로 나에게 새롭지 만 올바르게 배우고 싶습니다.

이 문제를 해결할 수 있도록 도와 주시면 감사하겠습니다.

감사합니다.

편집 : My Delphi 버전은 베를린 10.1이며 VCL을 사용합니다. 대상 플랫폼은 Windows 전용입니다.

편집 2 : https://www.dropbox.com/s/u7znetur723q6i2/DBApp.7z?dl=0 여기 내 프로젝트 파일입니다.

+1

먼저 명시 적 열거 자 값을 제거하고 간단하게 다음을 사용합니다. type TStatus = (Unknown, Dead, Owned, Borrowed); 적어도 RTTI는 과거에는 잘 돌아 가지 않았습니다. –

+0

StackOverflow에 대한 번호를 특별히 추가했습니다. 그 이유는 값을 할당하지 않는 것이 좋지 않은 것으로 간주되기 때문입니다. 그러나 나는 아쉽게도 현명하지 않다. –

+0

나는 명시 적으로 enum 값을 필요로하지 않는다면 그것을 사용하지 말라. AFAIC 그들은 Delphi에서 관용적이지 않고 주로 C 호환성 (Kylix)에 사용됩니다. –

답변

1

저는 State-Pattern의 구현을 포함하여 많은 것을 시도했습니다.

이 속성은이처럼 지금 보이는 :

property Status:String read ReadStatus write SetStatus; 

각 상태는,이 정보를, 내가 상수 "Statusbez"라고 그것이 무엇인지 상태에 대한 문자 정보를 보유하고 상수 문자열 지금 가지고 이제 데이터베이스에 전달됩니다. 나는 결국 끝낼 모든 상태의 열거 형 내 TStates 형에 액세스 상태를 설정하기 위해

function THund.ReadStatus():String; 
begin 
    if fStatus<>nil then Result:=fStatus.Statusbez; 
end; 

.

procedure THund.SetStatus(value:string); 
var 
    tempState:String; 
    i:Integer; 
begin 
    tempState:=fStatus.Statusbez; 
    i:=GetEnumValue(TypeInfo(TStates),value); 

    fStatus:=ChangeStatus(i); 
    if fStatus.Statusbez<>tempState then fUpdated:=True; 
end; 

changeStatus 함수는 초기화 할 상태를 간단히 결정합니다. 런타임에 상태를 설정하기 위해

function THund.ChangeStatus(value:Integer):TStatus; 
begin 
    fStatus.Free(); 

    case value of 
    Ord(Vorhanden):Result:=nil; 
    Ord(Verstorben):Result:=TDead.Create(); 
    Ord(Schwanger):Result:=nil; 
    Ord(Reserviert):Result:=nil; 
    Ord(Laeufig):Result:=nil; 
    Ord(Verkauft):Result:=nil; 
    Ord(Gnadenbrot):Result:=nil; 
    else Result:=nil; 
    end; 
end; 

내가 LiveBindings-원칙을 깨고 콤보 상자의 OnCloseUp-이벤트를 사용했다, 다음 줄은 콤보 상자의 텍스트 소요, 내 열거 형을 통해 구문 분석 얻는다 Enumvalue를 통해 상태를 할당합니다.

Hund.Status:=CB_Hund_Status.Items[CB_Hund_Status.ItemIndex]; 

나는 구성 요소의 이벤트에 의지해야만한다고해도 행복하지 않다.

어쨌든, 이제는 데이터베이스에서 단어를 사용하여 상태를 검사하고 여기 저기에 숫자와 switch-case 문 대신에 별도의 클래스 뒤에 논리를 넣을 수 있습니다.

관련 문제