如何将bitmasked值转换为选项对象?

时间:2012-04-03 14:51:58

标签: c# wpf xml bitmask

我必须读/写一个XML文件,将其数据存储为位掩码值。

e.g。

<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的十进制值转换为表示选项的对象模型?
  • 使用该对象将这些选项显示为用户选择和取消选择的选项?

2 个答案:

答案 0 :(得分: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
}

请注意我在枚举中使用2的幂。这些允许枚举使用二进制位位置表示离散值(参见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

答案 1 :(得分: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;
}

一旦从XML中读出值,调用EnumerateValues就很简单,只需将整数转换为AlarmData枚举,例如:

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

当然,您不必从EnumerateValues方法返回字符串。您需要做的就是将方法的结果绑定到列表或其他元素,Bob是您的叔叔。