2017-07-04 5 views
0

ich eine Enum Trole habenPopulate ComboBox mit Enum in Delphi mit MySQL

type 
    TRole = (Admin, Common); 

In meiner Datenbank (MySQL), habe ich eine Tabelle Benutzer mit einer Spalte Rolle vom Typ INTEGER . Ich möchte eine ComboBox mit den Rollen folgendermaßen füllen: Die ComboBox sollte "Administrator" in der Rolle Admin und "Common User" in der Rolle Common anzeigen; Wenn ich den Wert in der Datenbank speichere, sollte er als 0 für die Admin Rolle oder 1 für die Common Role (ihre jeweiligen Indizes) gespeichert werden.

Wenn das Rollenfeld angezeigt wird, sollte es auch als Strings angezeigt werden.

Kann mir bitte jemand erklären, wie kann ich das tun?

Antwort

0

Ich habe zwei verschiedene Ansätze verwendet, um dieses Problem zu lösen. Eine davon ist, RTTI zu verwenden, um den Namen aus der Enumeration abzuleiten, aber das würde in Ihrem Fall nicht funktionieren, also hier ist meine andere Methode, die bruteer ist:

(Sie können sich an Ihre Verwendung anpassen - beachten Sie meine tatsächlichen Funktionen sind von den Klassen, aber das ist nicht wichtig)

function EnumAsText(
    const pEnum: TRole): string; 
const 
    cResults : array[ TRole ] of string = 
    (
    {Admin}   'Admintrator', 
    {Common}   'Common User' 
); 
begin 
    Result := cResults[ pEnum ]; 
end; 

Dann das Drop füllen unten mit so etwas wie

procedure FillComboBox(Const pComboBox : TComboBox) 
var 
    iRole : TRole; 
begin 
    pComboBox.Items.Clear; 
    for iRole := low(TRole) to Hi(TRole) do 
    begin 
    pComboBox.Items.Add(EnumAsText(iRole)); 
    end; 
end; 

der Vorteil der Verwendung der const Array in EnumToText zu einem Fall Aussage gegenüber (die offensichtliche Möglichkeit, es zu tun) ist, dass, wenn Sie die enum erweitern, der Compiler wi Ich zwinge dich, die Funktion entsprechend zu modifizieren. Der ItemIndex des Kombinationsfelds entspricht Ihrem Integer-Feld.

+0

Fast da ... das Problem ist, dass es als ** INTEGER ** in der Datenbank gespeichert werden muss. Ihr Weg funktioniert, wenn ich sie als Strings speichern wollte –

+0

Nicht wenn, wie gesagt, Sie die ItemIndex -Eigenschaft des Kombinationsfelds verwenden, die eine ganze Zahl ist und genau zu Ihrem Feld entspricht. – Dsm

+0

Also, in diesem Fall würde ich nicht eine TDBComboBox verwenden, um dieses Feld zu speichern, sondern eine gemeinsame TComboBox und manuell durch den ItemIndex speichern? –

0

Sie brauchen keine TRole Enums für diese überhaupt. Füllen Sie ComboBox einfach mit Einträgen, so dass ihr Index den Datenbankwerten entspricht (0 = Administrator; 1 = Common User). Setzen Sie auch die Style-Eigenschaft von ComboBox auf csDropDownList.

procedure PopulateComboBox(const cb: TComboBox); 
begin 
    cb.Clear; 
    cb.Items.Add('Administrator'); // ItemIndex = 0 
    cb.Items.Add('Common User'); // ItemIndex = 1 
end; 

Nun, wenn Sie Ihre Daten mit SQL-Anfrage erhalten Sie gelten Wert von Rollen Spalte direkt auf ItemIndex Eigentum von Combobox:

Query.SQL.Text := 'select Name, Role from table where ID = :ID'; 
... 
if Query.FieldByName('Role').AsInteger in [0..1] then 
    RoleComboBox.ItemIndex := Query.FieldByName('Role').AsInteger 
else 
    raise Exception.Create('Role column value must be in range of 0..1'); 

Sie so ziemlich das gleiche, wenn Sie Speichern Rolle zur Datenbank. Verwenden Sie die ItemIndex-Eigenschaft als zu speichernden Wert:

if RoleComboBox.ItemIndex in [0..1] then 
begin 
    ... 
    Query.SQL.Text := 'update table set Role = :Role where ID = :ID'; 
    Query.ParamByName('Role').AsInteger := RoleComboBox.ItemIndex; 
    Query.ExecSQL; 
end 
else 
    raise Exception.Create('Invalid role index');