0

I have to map a Flags Enumeration to multiple combo boxes.

For example, the first 2 bits need to correspond to a combo box for screen contrast setting:

Bit 0 - 1: Contrast (0=Low / 1 = Medium / 2=high)

Bits 2 & 3 need to correspond to the speech volume

Bit 2 - 3: Speech volume (0=Low / 1 = Medium / 2 = High)

and bits 4 & 5 correspond to the Buzzer volume.

Bit 4 – 5: Buzzer volume (0=Low / 1 = Medium / 2 = High)

Bit 6 corresponds to Entry or Exit (i.e. if it's on it's Entry, if it's off it's exit)

Bit 6: Entry/exit indication

My Flags enum is defined as:

[Flags]
public enum RKP
{
    Contrast0 = 1,              // bit 0
    Contrast1 = 2,              // bit 1
    SpeechVolume2 = 4,          // bit 2
    SpeechVolume3 = 8,          // bit 3
    BuzzerVolume4 = 16,         // bit 4
    BuzzerVolume5 = 32,         // bit 5
    EntryExitIndication = 64,   // bit 6
}

What's the best way to map these to the appropriate combo boxes, and then convert the values of each combo box to the correct enumeration value to save it?

DaveDev
  • 41,155
  • 72
  • 223
  • 385
  • 1
    If you insist on shrinking the info size, you should make a fixed size struct and provide functions that extract and set info. The rest should be hard coded. – SimpleVar Oct 02 '12 at 11:30
  • Pherhaps this could give you an idea: http://www.thejoyofcode.com/Xaml_ObjectDataProvider._They_really_did_think_of_everything.aspx – Florian Gl Oct 02 '12 at 12:02

2 Answers2

2

With your solution it is possible to create conflicting values, for example combining MediumSpeechVolume and HighSpeechVolume as Dan Puzey pointed out.

Does your solution have to be a flagged enum? This could be solved using a simple class with the 4 required enums inside as properties. If you need the exact bit pattern generated by your current flags enum, create another property to expose, with custom get and set to translate the current values of your 4 main properties to the required bit pattern and back.

w5l
  • 5,341
  • 1
  • 25
  • 43
  • 1
    I disagree with your first statement. If the value is 4, it seems obvious to me that the contrast and buzzer are low, the speech medium, and exit indicated. I.e. low values can be specified without every value being 0. I like your second paragraph as a preferred solution, and have upvoted you for that. – Tim S. Oct 02 '12 at 13:32
  • 1
    I also disagree with the first statement, but it *is* convoluted: you can only detect a `Low` value from the absence of `Medium` and `High`. It would definitely make more sense to define a separate structure to parse these bits into three values. – Dan Puzey Oct 02 '12 at 13:42
  • Youre right, I have editted the answer to remove the incorrect statement, thanks for pointing out. – w5l Oct 02 '12 at 14:13
0
[Flags]
public enum RKP
{
    LowContrast = 0,
    MediumContrast = 1,         // bit 0
    HighContrast = 2,           // bit 1

    LowSpeechVolume = 0,
    MediumSpeechVolume = 4,     // bit 2
    HighSpeechVolume = 8,       // bit 3

    LowBuzzerVolume = 0,
    MediumBuzzerVolume = 16,    // bit 4
    HighBuzzerVolume = 32,      // bit 5

    ExitIndication = 0,
    EntryIndication = 64,       // bit 6
}

contrastComboBox.ItemsSource = new[] { RKP.LowContrast, RKP.MediumContrast, RKP.HighContrast };
contrastComboBox.SelectedItem = currentValue & (RKP.MediumContrast | RKP.HighContrast);
//and so on for each combo box...

//and when you want the result:
RKP combinedFlag = (RKP)contrastComboBox.SelectedItem | //other combo box items

You'll probably want to do something about what strings will be shown, but that's the basic idea.

Tim S.
  • 55,448
  • 7
  • 96
  • 122
  • 2
    This doesn't explain how you'd go about selecting the correct value to be *displayed* in each combobox. Further, since it's possible to have an enum value of `12` (both `MediumSpeechVolume` *and* `HighSpeechVolume`), it's easy to come unstuck with this method. Nice attempt, but I think the OP needs to rethink the approach. – Dan Puzey Oct 02 '12 at 12:10
  • 1
    @DanPuzey Is there anything wrong with `currentValue & (RKP.MediumContrast | RKP.HighContrast)` and my use of `|` to join the individual values into the combined flag? It seems to me that it should result in correct values. Granted, a value of `12` would cause problems, and shouldn't be considered valid, just as `-1` shouldn't be considered valid. I agree with @WillemDuncan's second paragraph: a class with separate properties would be preferable. However I think it *could* work as the asker wishes. – Tim S. Oct 02 '12 at 13:31
  • It may not have been clear, but I was definitely intending to criticize the question's approach rather than yours. You're right that `-1` shouldn't be valid - but then, `-1` would not be a valid value in the enum. `12` *would* be, and it's for that reason that I think the OP needs to rethink. Your approach is probably the best it could be given the wonky data model! – Dan Puzey Oct 02 '12 at 13:37
  • 1
    @TimS.' solution to get individual values back works, combining all possible values of one set. However adding multiple `0` flag values gives wrong results: `var x = RKP.MediumContrast | RKP.HighSpeechVolume | RKP.EntryIndication;` will give `ExitIndication, LowContrast, LowBuzzerVolume, MediumContrast, HighSpeechVolume, EntryIndication`. – w5l Oct 02 '12 at 14:17
  • Ah yes, I see that is an issue. It makes detecting a "Low" value convoluted, as you must do it by seeing the absence of another value, not just by checking , e.g. `myRKP.HasFlag(RKP.LowContrast)`, and makes the `ToString` result often nonsensical, as in your example. It's not completely impossible to work with, but certainly a poor choice (when you can choose another way). – Tim S. Oct 02 '12 at 17:49