2013-06-05 31 views
3

我使用TObjectBindSourceAdapter使用livebindings與對象。 與TObjectBindSourceAdapter使用的對象的屬性之一具有枚舉類型,但在我的對象中使用枚舉類型時從不會生成適配器中的字段如何(正確)使用枚舉類型livebindings(TObjectBindSourceAdapter)

我現在找到的唯一解決方案是在我的對象中定義枚舉類型爲整數,並對它進行類型轉換。這似乎工作正常,但你必須保持類型轉換和返回枚舉類型和整數。

下面是一些示例代碼來解釋我的意思。

它採用枚舉類型,我最初嘗試似乎並沒有工作

第一個例子:

uses Data.Bind.ObjectScope; 

Type 
    TMyEnumtype = (meOne, meTwo, meThree); 

    TMyObject = class 
    public 
     MyEnumType: TMyEnumtype; 
    end; 

procedure TForm9.But1Click(Sender: TObject); 
var 
    MyObject: TMyObject; 
    aBindSourceAdapter: TBindSourceAdapter; 
begin 
    MyObject := TMyObject.Create; 
    MyObject.MyEnumType := meTwo; 
    aBindSourceAdapter := TObjectBindSourceAdapter<TMyObject>.Create(nil, MyObject, False); 
    if aBindSourceAdapter.FindField('MyEnumType') <> nil then 
    ShowMessage('MyEnumType found') 
    else 
    showmessage('MyEnumType not found'); 
    FreeAndNil(MyObject); 
    FreeAndNil(aBindSourceAdapter); 
end; 

,似乎通過類型轉換爲整數

uses Data.Bind.ObjectScope; 

Type 
    TMyEnumtype = (meOne, meTwo, meThree); 

    TMyObject = class 
    public 
     MyEnumType: integer; 
    end; 

procedure TForm9.But1Click(Sender: TObject); 
var 
    MyObject: TMyObject; 
    aBindSourceAdapter: TBindSourceAdapter; 
    aEnumType : TMyEnumtype; 
begin 
    MyObject := TMyObject.Create; 
    MyObject.MyEnumType := Integer(meTwo); 
    aBindSourceAdapter := TObjectBindSourceAdapter<TMyObject>.Create(nil, MyObject, False); 
    if aBindSourceAdapter.FindField('MyEnumType') <> nil then 
    ShowMessage('MyEnumType found') 
    else 
    showmessage('MyEnumType not found'); 

    aEnumType := TMyEnumtype(aBindSourceAdapter.FindField('MyEnumType').GetTValue.AsInteger); 

    if aEnumType = meTwo then 
    showmessage('meTwo'); 

    FreeAndNil(MyObject); 
    FreeAndNil(aBindSourceAdapter); 
end; 

我在想,如果工作第二個例子別人都遇到過這個問題,如果有可能是一些其他的解決方案來解決這個沒有恢復到整數,同時繼續使用枚舉類型。我也不確定我的解決方法是否是通用的方法。

+1

我認爲你別無選擇 - 我很早以前就得出結論:鑄造爲整數是最好的解決方案。 –

回答

2

我認爲最好的辦法就是註冊一個轉換器。它原來是很容易的,但只能通過VCL源代碼後挖。我沒有找到任何有用的文檔。但在這裏。

unit MyConverters; 

interface 

uses System.Rtti, System.Bindings.Outputs; 

type 
    TMyEnum = (Value1, Value2, Value3); 

implementation 

procedure RegisterConverters; 
begin 
    TValueRefConverterFactory.RegisterConversion(TypeInfo(TMyEnum), TypeInfo(string), 
    TConverterDescription.Create(
     procedure(const InValue: TValue; var OutValue: TValue) 
     var 
     MyEnum: TMyEnum; 
     S: string; 
     begin 
     MyEnum := InValue.AsType<TMyEnum>; 
     case MyEnum of 
      Value1: S := 'First Value'; 
      Value2: S := 'Second Value'; 
      Value3: S := 'Third Value'; 
      else  S := 'Other'; 
     end; 
     OutValue := TValue.From<string>(S); 
     end, 
     'TMyEnumToString', 
     'TMyEnumToString', 
     '', // TODO what is the AUnitName param used for? 
     True, // TODO what is ADefaultEnabled used for? What does it mean? 
     'Converts a TMyEnum value to a string', 
     nil) 
); 
end; 

initialization 
    RegisterConverters; 
end. 

概括地說,你叫TValueRefConverterFactor.RegisterConversion()和傳遞:

  • 的類型,這種轉換器轉換FROM
  • ,這種轉換器轉換TO
  • 一個TConverterDescription類型其中包含一個匿名過程以實際執行轉換以及其他一些元數據。

在上面的代碼中,initialization部分調用RegisterConverters,使所有必要的是包含在你的項目單位和現場綁定框架將要使用時,它需要一個TMyEnum值轉換爲string轉換器。

0

鑄造枚舉整型和回真的是要適應這種情況的適當方式。比方說,例如...

type 
    TMyEnum = (meOne, meTwo, meThree); 

正如你已經證明,這些都可以鑄造爲整數。以整數形式進行投射時,它將使用定義中列出每一個的索引。所以......

0 = meOne 
1 = meTwo 
2 = meThree 

你會投TMyEnum作爲Integer喜歡...

Something := Integer(MyEnumValue); 

,然後將它轉換回喜歡...

Something := TMyEnum(MyIntegerValue); 

這被廣泛用於解決你確切的問題,我自己一直在使用它。我早就調查相同的情況下,來到它真的做到這一點的唯一方法得出結論 - 除非你想要做一些更復雜的轉換使用字符串,如...

function MyEnumToStr(const MyEnum: TMyEnum): String; 
begin 
    case MyEnum of 
    meOne: Result:= 'meOne'; 
    meTwo: Result:= 'meTwo'; 
    meThree: Result:= 'meThree'; 
    end; 
end; 

function StrToMyEnum(const Str: String): TMyEnum; 
var 
    S: String; 
begin 
    S:= UpperCase(Str); 
    if S = 'MEONE' then Result:= meOne 
    else if S = 'METWO' then Result:= meTwo 
    else if S = 'METHREE' then Result:= meThree; 
end; 

(我敢肯定還有其他使用if語句的方法StrToMyEnum

以這種方式使用字符串可以使事情更具可讀性。一個更真實的例子...

type 
    TCustomerType = (cmRetail, cmWholesale, cmDesigner); 

哪裏..​​.

cmRetail = 'Retail Customer' 
cmWholesale = 'Wholesale Customer' 
cmDesigner = 'Designer Customer'