简体   繁体   English

C#在列表框上禁用Ctrl键

[英]C# Disable Ctrl key on a ListBox

I'm looking to disable the Ctrl key on a ListBox. 我想禁用ListBox上的Ctrl键。 I followed the example at Disable list box CTRL+C & CTRL+X in D&D . 我按照D&D中的禁用列表框CTRL + C&CTRL + X的示例进行操作。 It took some playing, since I'm using System.Windows.Input and using System.Windows.Forms . 因为我正在using System.Windows.Inputusing System.Windows.Forms ,所以花了一些时间。 I was able to resolve the references, except for the e object. 我能够解析引用,除了e对象。 It tells me there is no Handled definition within System.Windows.Forms.PreviewKeyDownEventArgs . 它告诉我System.Windows.Forms.PreviewKeyDownEventArgs没有Handled定义。 What am I missing here? 我在这里想念什么? Thanks! 谢谢!

  private void lbSigns_PreviewKeyDown(object sender, 
                System.Windows.Forms.PreviewKeyDownEventArgs e)
    {
        //
        // This if statement detects if the Control Key is pressed.
        //
        if ((System.Windows.Input.Keyboard.Modifiers & 
          System.Windows.Input.ModifierKeys.Control) == 
                 System.Windows.Input.ModifierKeys.Control)
        {
            e.Handled = true;
        }
    }

OK, I'm getting closer with @Tsukasa 's code. 好的,我与@Tsukasa的代码越来越接近。 Here's what I have now. 这就是我现在所拥有的。

    List<int> alreadySelectedIndexes = new List<int>();

    private void lbSigns_SelectedIndexChanged(object sender, EventArgs e)
    {

        TrackSelection((ListBox)sender, alreadySelectedIndexes);

        bool allowSelection = false;

        int currentSelectedIndex = -1;

        //make sure we have an item selected
        if (!lbSigns.SelectedIndex.Equals(-1))
        {
            //if first selection we allow it
            if (alreadySelectedIndexes.Count.Equals(1))
            {
                allowSelection = true;
            }
            else
            {
                //get the last item index that was selected from our list
                currentSelectedIndex = alreadySelectedIndexes[alreadySelectedIndexes.Count - 1];

                //make sure we have a previous index item
                if ((currentSelectedIndex - 1) >= 0)
                {
                    //check if previous item before currently selected is checked
                    if (lbSigns.GetSelected(currentSelectedIndex - 1))
                    {
                        allowSelection = true;
                    }
                }

                //make sure we have a next index item
                if ((currentSelectedIndex + 1) <= lbSigns.Items.Count - 1)
                {
                    //check if next item after currently selected is checked
                    if (lbSigns.GetSelected(currentSelectedIndex + 1))
                    {
                        allowSelection = true;
                    }
                }
                //make sure we have both a next and a previous item
                if (((currentSelectedIndex - 1) >= 0) && ((currentSelectedIndex + 1) <= lbSigns.Items.Count - 1))
                {
                    //if both are selected, deny the selection
                    if (lbSigns.GetSelected(currentSelectedIndex - 1) && lbSigns.GetSelected(currentSelectedIndex + 1))
                    {
                        allowSelection = false;
                    }
                }
            }
        }

        //unselect item because it wasn't before or after an already selected item
        if (!allowSelection && !currentSelectedIndex.Equals(-1))
        {
            lbSigns.SetSelected(currentSelectedIndex, false);
        }
    }

    private void TrackSelection(ListBox listBox, List<int> alreadySelectedList)
    {
        ListBox.SelectedIndexCollection indexCollection = listBox.SelectedIndices;

        foreach (int index in indexCollection)
        {
            if (!alreadySelectedList.Contains(index))
            {
                alreadySelectedList.Add(index);
            }
        }

        foreach (int index in new List<int>(alreadySelectedList))
        {
            if (!indexCollection.Contains(index))
            {
                alreadySelectedList.Remove(index);
            }
        }
    }

But, this is letting me de-select an item surrounded by 2 selected items. 但是,这让我取消选择了2个选定项目周围的项目。 Once de-selected, it won't let me re-select that item, even though it has selected items on either side of it. 取消选择后,即使它已在任一侧选择了项目,也不允许我重新选择该项目。 I added in the section that follows the comment: //make sure we have both a next and a previous item 我在注释后面的部分中添加了: //make sure we have both a next and a previous item

Updated 2 更新2

Ok this doesn't allow deselection between selected items, although there is another issue. 好的,这不允许在选定的项目之间取消选择,尽管还有另一个问题。

Issue: you can hold down the mouse button and ctrl+mouse left and drag up and down. 问题:您可以按住鼠标按钮,向左按住Ctrl +鼠标并上下拖动。 This doesn't call the event until finished. 直到完成,才调用该事件。 I'm not sure what event to hook to try and correct that. 我不确定要尝试纠正哪个事件。

I do however have a better way I can post later. 不过,我确实有更好的方式可以稍后发布。 I would create a global keyboard hook on both the left and right control keys. 我将在左右控制键上都创建一个全局键盘钩。 In the event that fires when that key is detected. 如果检测到该键时触发。 If the ListBox has input focus then we handle the key causing only the shift button being able to be used to select multiple items. 如果ListBox具有输入焦点,则我们将处理该键,从而仅使Shift按钮能够用于选择多个项目。 You want to make sure it's only when input focus is on the ListBox otherwise you would be eating the key for all other apps since it's a global hook. 您要确保仅当输入焦点位于ListBox上时,否则它将成为所有其他应用程序的键,因为它是全局钩子。

        //hold already selected items. Last item will be last selected
    List<int> alreadySelectedIndexes = new List<int>();

    //used to skip listBox1_SelectedIndexChanged on TrackSelection
    bool ignoreSelectedChanged = false;

    private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
    {
        //prevent overflow of caused by TrackSelection
        if (!ignoreSelectedChanged)
        {
            TrackSelection((ListBox)sender, alreadySelectedIndexes);

            bool allowSelection = false;

            int currentSelectedIndex = -1;

            //make sure we have an item selected
            if (!listBox1.SelectedIndex.Equals(-1))
            {
                //if first selection we allow it
                if (alreadySelectedIndexes.Count.Equals(1))
                {
                    allowSelection = true;
                }
                else
                {
                    //get the last item index that was selected from our list
                    if ((alreadySelectedIndexes.Count - 1) >= 0)
                    {
                        currentSelectedIndex = alreadySelectedIndexes[alreadySelectedIndexes.Count - 1];

                        //make sure we stay in array range
                        if ((currentSelectedIndex - 1) >= 0)
                        {
                            //check if previous item before currently selected is checked
                            if (listBox1.GetSelected(currentSelectedIndex - 1))
                            {
                                allowSelection = true;
                            }
                        }

                        //make sure we stay in array range
                        if ((currentSelectedIndex + 1) <= listBox1.Items.Count - 1)
                        {
                            //check if next item after currently selected is checked
                            if (listBox1.GetSelected(currentSelectedIndex + 1))
                            {
                                allowSelection = true;
                            }
                        }
                    }
                }

                bool isSelected = false;
                if (currentSelectedIndex >= 0)
                {
                    isSelected = listBox1.GetSelected(currentSelectedIndex);

                    if (!isSelected)
                    {
                        //we can remove it from the list now
                        alreadySelectedIndexes.Remove(currentSelectedIndex);

                        //reselect it if in the middle of already selected items
                        if (alreadySelectedIndexes.Contains(currentSelectedIndex + 1) && alreadySelectedIndexes.Contains(currentSelectedIndex - 1))
                        {
                            ignoreSelectedChanged = true;
                            allowSelection = true;
                            listBox1.SetSelected(currentSelectedIndex, true);
                        }
                    }
                }
            }

            if (!currentSelectedIndex.Equals(-1) && !allowSelection)
            {
                ignoreSelectedChanged = true;
                listBox1.SetSelected(currentSelectedIndex, false);
            }

            //unselect item because it wasn't before or after the last selected item

        }
        ignoreSelectedChanged = false;
    }

    private void TrackSelection(ListBox listBox, List<int> alreadySelectedList)
    {
        ListBox.SelectedIndexCollection indexCollection = listBox.SelectedIndices;

            foreach (int index in indexCollection)
            {
                if (!alreadySelectedList.Contains(index))
                {
                    alreadySelectedList.Add(index);
                }
            }

        foreach (int index in new List<int>(alreadySelectedList))
        {
            if (!indexCollection.Contains(index))
            {
                //remove first index in list
                alreadySelectedList.Remove(index);
                //add index back to end of list so we know what was deselected
                alreadySelectedList.Add(index);
            }
        }
    }
            using System;
            using System.Collections.Generic;
            using System.ComponentModel;
            using System.Data;
            using System.Drawing;
            using System.Linq;
            using System.Text;
            using System.Threading.Tasks;
            using System.Windows.Forms;

            namespace listBoxWinforms
            {
                public partial class Form1 : Form
                {
                    public Form1()
                    {
                        InitializeComponent();
                    }

                    private void listBox1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
                    {
                        if (e.Control)
                        {
                            return;
                        }
                    }
                }
            }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM