Как преобразовать битовые маски в объект параметров? - PullRequest
1 голос
/ 03 апреля 2012

Мне нужно прочитать / записать файл 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 в объектную модель, которая представляет параметры?
  • использовать этот объект для отображения этих параметровдля пользователя, чтобы выбрать и отменить выбор?

Ответы [ 2 ]

3 голосов
/ 03 апреля 2012

Объявите перечисление следующим образом:

[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
}

Обратите внимание на мое использование степеней двух в перечислении.Они позволяют перечислению представлять дискретные значения, используя двоичные битовые позиции (см. Почему разрешения перечисления часто имеют значения 0, 1, 2, 4? )

, затем анализируют ваше значение в целое число иприведите это к типу 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...
}

Есть много сообщений о том, как использовать enum в комбинированном ящике WPF или переключателях, например:

Привязка данных свойства enum к ComboBox в WPF

2 голосов
/ 03 апреля 2012

Как насчет использования возможностей перечислений, чтобы помочь вам на вашем пути:

[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, просто приведите целое число как AlarmDataenum, например:

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

Конечно, вам не нужно возвращать строки из метода EnumerateValues.Все, что вам тогда нужно будет сделать, это связать результат метода со списком или каким-то другим элементом, и Боб станет вашим дядей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...