Search code examples
wpfxamlenumsattached-properties

Attached DependencyProperty with Enums act weird


I defined an attached dependency property with type InteractionMode (which is an enum). That looks like that:

[Flags]
public enum InteractionMode
{
    Add,
    AppZone,
    Shortcuts,
    MagnetSelection,
    RowColumnChoosing
}

public static readonly DependencyProperty UserSpaceInteractionMode = DependencyProperty.RegisterAttached(
        "UserSpaceInteractionMode", 
        typeof(InteractionMode),
        typeof(LeapConnectorProperties),
        new FrameworkPropertyMetadata(InteractionMode.None, FrameworkPropertyMetadataOptions.None));

public static InteractionMode GetUserSpaceInteractionMode(DependencyObject element)
{
    if (element == null)
    {
         throw new ArgumentNullException("element");
    }
    return (InteractionMode)element.GetValue(UserSpaceInteractionMode);
}

public static void SetUserSpaceInteractionMode(DependencyObject element, InteractionMode value)
{
    if (element == null)
    {
        throw new ArgumentNullException("element");
    }
    element.SetValue(UserSpaceInteractionMode, value);
}

Furthermore i use this dependency property to mark specific UIElements in XAML:

<Grid ns:depProp.UserSpaceInteractionMode="Shortcuts,MagnetSelection">

Thus far everything is okay. Unfortunately when asking for those enums

InteractionMode iMode = depProp.GetUserSpaceInteractionMode(grid);

I get a weird result. It doesn't throw errors but the enums shown by Visual Studio when debugging are different ones, than those I defined in XAML (for example AppZone | Shortcuts instead of Shortcuts | MagnetSelection).

Even worse when checking all enum flags from InteractionMode with iMode.hasFlag(flag) the result is also different compared to what Visual Studio says (for example it says true when asking iMode.hasFlag(InteractionMode.Add))

I think I'm using enums somehow wrong, but I've no idea whats the problem. Thanks for any suggestions!


Solution

  • Having not specifically done what you are doing, I have seen other similar flag settings, but the enumerations needed to be binary when you are allowing more than one via OR possibilities.

    The default is implied as 
    public enum InteractionMode
    {
        Add = 0,
        AppZone = 1,
        Shortcuts = 2,
        MagnetSelection = 3,
        RowColumnChoosing = 4
    }
    
    Change to
    public enum InteractionMode
    {
        Add = 1,
        AppZone = 2,
        Shortcuts = 4,
        MagnetSelection = 8,
        RowColumnChoosing = 16
    }
    

    So, if a user in the original picks Shortcuts and MagnetSelection as options, looking at binary of

                 BINARY
    Shortcut 2 = 0010
    Magnet   3 = 0011
    and you get 
             5 = 0101 binary, so this triggers the "Add" as "1" in the rightmost position.
    

    Now, via the binary sample changed to for shortcuts and magnetSelection you would get

    Shortcut  4 = 0100
    Magnet    8 = 1000
    resulting in 12
    OR'd     12 = 1100
    

    So now the test will properly recognize one or the other.