ModifierKeys按位和

时间:2015-12-11 14:36:15

标签: c# winforms key-bindings

我在Chart控件上向scrollwheel事件添加了一些功能,我很好奇大多数文档在确定按下哪个修改键时出现的按位AND(例如https://msdn.microsoft.com/en-us/library/yazd4ct6(v=vs.110).aspx

void Chart_MouseWheel(object sender, MouseEventArgs e)
{
    //if ((ModifierKeys & (Keys.Shift | Keys.Control)) == (Keys.Shift | Keys.Control)) 
    if(ModifierKeys == (Keys.Shift | Keys.Control))
    {
        //+/- 5 chart threshold with control and shift held
        Threshold += (decimal)(e.Delta / 24m / 100m);
    }
    //else if ((ModifierKeys & Keys.Shift) == Keys.Shift)
    else if(ModifierKeys == Keys.Shift)
    {
        //+/- 1 chart threshold change with shift held
        Threshold += (decimal)(e.Delta / 120m / 100m);
    }
    //else if ((ModifierKeys & Keys.Control) == Keys.Control)
    else if(ModifierKeys == Keys.Control)
    {
        var selectedIndex = styledComboBox1.SelectedIndex;
        selectedIndex += -1*(e.Delta / 120);

        if (selectedIndex < 0) selectedIndex = 0;
        if (selectedIndex > (styledComboBox1.Items.Count - 1)) selectedIndex = styledComboBox1.Items.Count - 1;

        styledComboBox1.SelectedIndex = selectedIndex;
    }
    else
    {
        AxisMax += 0.02 * e.Delta / 120;
    }
}

注释和未注释的if / else if行都会产生相同的结果,三种组合(Shift + Control,Shift,Control)中的每一种产生所需的效果,所以我只是想知道为什么它在未注释的情况下有效场景。

此外,当我没有检查Shift + Control作为第一个条件时,它只会落入Shift块 - 为什么会这样?

2 个答案:

答案 0 :(得分:1)

只要您没有按任何其他ModifierKeys,评论代码的工作方式与未注释的代码相同:尝试按ALT并且您应该注意区别。

如果你跳过第一次检查,第二次检查未注释的代码说“如果只按下shift”,而评论的人说“如果按下shift,无论是否按下其他修改器”

因此,跳过第一张支票,按CTRL + SHIFT与未注释的支票不匹配,但与评论支票匹配

答案 1 :(得分:1)

我对这个很开心,好问题!

TL; DR按位并从枚举中删除任何其他标志,以防您想要忽略它们,只查看您指定的键是否被按下。

下面是一个控制台应用程序,它显示每个操作的位,以及为什么它按下CTRL + SHIFT时有和没有按位AND的工作方式相同。按位AND用于过滤掉任何其他修饰符:无论是否按下ALT或WINDOWS,它都会使检查与CTRL + SHIFT进行比较。每个都有用例(你可能只想忽略alt键,这很好,你可以使用它,或者你可能想确保它没有被按下,只有CTRL和SHIFT)。

我从right from the source.

中获得的ModifierKeys定义
public class Program
{
    [Flags]
    private enum ModifierKeys
    {
        None = 0,
        Alt = 1,
        Control = 2,
        Shift = 4,
        Windows = 8
    }

    static void Main(string[] args)
    {
        ModifierKeys none = ModifierKeys.None;
        ModifierKeys alt = ModifierKeys.Alt;
        ModifierKeys control = ModifierKeys.Control;
        ModifierKeys shift = ModifierKeys.Shift;
        ModifierKeys windows = ModifierKeys.Windows;
        ShowEnums(none, alt, control, shift, windows);

        ShowAddingFlags(control, shift);

        ShowBitwiseAnd(none, alt, control, shift, windows);


        CompareWithShiftAndControl(alt, control, shift);

        Console.ReadKey();
    }

    private static void ShowBitwiseAnd(params ModifierKeys[] ms)
    {
        List<ModifierKeys> mods = new List<ModifierKeys>();
        mods.AddRange(ms);

        ModifierKeys c = ModifierKeys.None;

        Console.WriteLine("Adding all...");

        foreach (var m in mods)
        {
            Console.WriteLine(GetBinaryString(m));
            c = c | m;
        }

        Console.WriteLine(GetBinaryString(c));
        Console.WriteLine(c);
        Console.WriteLine();
    }

    private static void CompareWithShiftAndControl(params ModifierKeys[] ms)
    {
        var withAlt = ModifierKeys.Alt | ModifierKeys.Control | ModifierKeys.Shift;
        var withoutAlt = ModifierKeys.Control | ModifierKeys.Shift;

        Console.WriteLine("Using bitwise And:" );

        var formatter = "{0} & {1} = {2}";
        Console.WriteLine(formatter, GetBinaryString(withAlt), GetBinaryString(withoutAlt), GetBinaryString(withAlt & withoutAlt));
        Console.WriteLine(formatter, withAlt, withoutAlt, withAlt & withoutAlt);

    }

    private static void ShowAddingFlags(params ModifierKeys[] ms)
    {
        List<ModifierKeys> mods = new List<ModifierKeys>();
        mods.AddRange(ms);

        ModifierKeys c = ModifierKeys.None;

        Console.WriteLine("Adding Control and Shift...");

        foreach (var m in mods)
        {
            Console.WriteLine(GetBinaryString(m));
            c = c | m;
        }

        Console.WriteLine(GetBinaryString(c));
        Console.WriteLine(c);
        Console.WriteLine();
    }

    private static string GetBinaryString(ModifierKeys modifierKeys)
    {
        return Convert.ToString((int)modifierKeys, 2).PadLeft(8, '0'); 
    }

    private static void ShowEnums(params ModifierKeys[] ms)
    {
        List<ModifierKeys> mods = new List<ModifierKeys>();
        mods.AddRange(ms);

        foreach (var m in mods)
        {
            Console.WriteLine(m);
            Console.WriteLine(GetBinaryString(m));
        }

        Console.WriteLine();
    }
}