2012-04-03 68 views
1

我必須讀/寫一個XML文件,將其數據存儲爲位掩碼值。如何將位掩碼值轉換爲選項對象?

例如

<panel> 
    <options arming="21" opt_b="51" opt_c="6" /> 
</panel> 
在這種情況下

arming具有值21,但是這對應於字節以下字符串:

10101 

和那些字節對應於以下列表選項0,2,4:

  • 位0:強迫臂
  • 位1:最終門
  • 位2:退出故障
  • 位3:禁止篡改
  • 位4:顯示
  • 位8:再裝
  • 位9:線
  • 位10:擴展塊

對我來說最好的方法是什麼

  • 將此值從21的十進制值轉換爲表示選項的對象模型?
  • 使用該對象將這些顯示爲用戶選擇和取消選擇的選項?因此

回答

3

聲明一個枚舉:

[Flags] 
public enum ArmingFlags { 
    None=0 
    Forced_arm = 1 
    Final_door = 2 
    Exit_fault = 4 
    Inhibit_tamper = 8 
    Display = 16 
    Rearm = 32 
    Line = 64 
    Extend_block = 128 
} 

注意我使用的枚舉的兩個大國的。這允許枚舉使用二進制位的位置(見Why do enum permissions often have 0, 1, 2, 4 values?

然後解析您的值轉換成整數,表示離散值和鑄造的一種類型ArmingFlags(注意,未測試的代碼領先,但應工作):

ArmingFlags flagsVal = ArmingFlags.None; 
Int32 val; 
if (Int32.TryParse(armingString, out val)) { 
    flagsVal = (ArmingFlags)val; 
} 

// Then you can test it for expected values: 
if ((flagsVal & ArmingFlags.Rearm) == ArmingFlags.Rearm) { 
    //The Rearm bit was set... 
} 

有很多關於如何在WPF組合框或單選按鈕使用枚舉,例如職位:

Databinding an enum property to a ComboBox in WPF

+0

謝謝,這工作。注意 - 我已經編輯了答案來添加一些括號。只是想知道,爲什麼要寫'((flagsVal&ArmingFlags.Rearm)== ArmingFlags.Rearm)'? '(flagsVal == ArmingFlags.Rearm)'不能工作嗎?這似乎是多餘的,但我見過其他一些例子。當我用兩個例子對它進行測試的時候,它工作。 – DaveDev 2012-04-03 15:51:40

+0

您想要測試(可能)多個標誌中的單個標誌。例如,您在OP(10101)中顯示的值不等於ArmingFlags.Forced_arm(它是'ArmingFlags.Forced_arm&ArmingFlags.Exit_fault&ArmingFlags.Display')。要測試特定的標誌位,需要過濾掉所有其他1的值,然後執行相等性測試。 – 2012-04-03 16:06:04

+0

真的這是最好的解釋在我上面鏈接的帖子:http://stackoverflow.com/questions/9811114/why-do-enum-permissions-often-have-0-1-2-4-values/9811145#9811145 – 2012-04-03 16:06:49

2

如何使用枚舉的力量來幫助你走好人生路:

[Flags] 
public enum AlarmData 
{ 
    ForcedArm = 1, 
    FinalDoor = 2, 
    ExitFault = 4, 
    InhibitTamper = 8, 
    Display = 16, 
    Rearm = 32, 
    Line = 64, 
    ExtendBlock = 128 
} 

private static Dictionary<AlarmData, string> alarmDataLookup = new Dictionary<AlarmData, string> 
{ 
    { AlarmData.ForcedArm, "Forced arm" }, 
    { AlarmData.FinalDoor, "Final door" }, 
    { AlarmData.ExitFault, "Exit fault" }, 
    { AlarmData.InhibitTamper , "Inhibit tamper" }, 
    { AlarmData.Display , "Display" }, 
    { AlarmData.Rearm , "Rearm" }, 
    { AlarmData.Line , "Line" }, 
    { AlarmData.ExtendBlock , "Extend block" } 
}; 

public IEnumerable<string> EnumerateValues(AlarmData data) 
{ 
    return from pair in alarmDataLookup 
      where data.HasFlag(pair.Key) 
      select pair.Value; 
} 

調用EnumerateValues很簡單,一旦你讀出從XML值,只投整數作爲AlarmData枚舉,如:

int value = GetAlarmValueFromXml(); 
var bindableValues = EnumerateValues((AlarmData)value); 

當然,你不必從EnumerateValues方法返回字符串。然後你需要做的就是將方法的結果綁定到列表或其他元素,而鮑勃是你的叔叔。