Winforms -如何防止列表框项选择

2nc8po8w  于 2023-10-23  发布在  其他
关注(0)|答案(5)|浏览(122)

在WinForms中,我有一个循环运行在一个列表框上,选择项目。
在这段时间里,我不希望用户用鼠标或按键选择列表框中的项目。
我查看了MyListbox.enabled=false,但它会使所有项目变成格雷。我不想那样
如何防止选择列表框中的项目?

wbrvyc0a

wbrvyc0a1#

我也想要一个只读列表框,最后,经过大量的搜索,从http://ajeethtechnotes.blogspot.com/2009/02/readonly-listbox.html找到了这个:

public class ReadOnlyListBox : ListBox
{
    private bool _readOnly = false;
    public bool ReadOnly
    {
        get { return _readOnly; }
        set { _readOnly = value; }
    }

    protected override void DefWndProc(ref Message m)
    {
        // If ReadOnly is set to true, then block any messages 
        // to the selection area from the mouse or keyboard. 
        // Let all other messages pass through to the 
        // Windows default implementation of DefWndProc.
        if (!_readOnly || ((m.Msg <= 0x0200 || m.Msg >= 0x020E)
        && (m.Msg <= 0x0100 || m.Msg >= 0x0109)
        && m.Msg != 0x2111
        && m.Msg != 0x87))
        {
            base.DefWndProc(ref m);
        }
    }
}
4zcjmb1e

4zcjmb1e2#

Listbox.SelectionMode属性切换为SelectionMode.None

编辑如我所见,设置为SelectionMode.None取消选择所有以前选择的项目,并抛出一个异常,如果SetSelected是在列表框中调用。

我认为想要的行为是不可能的(如果不想用Enabled=false灰色化项目)。

r9f1avp5

r9f1avp53#

创建一个从Listbox中移除焦点的事件处理程序,并将该处理程序订阅到Listbox的GotFocus事件。这样,用户将永远无法选择列表框中的任何内容。下面的代码行使用内联匿名方法来实现这一点:

txtBox.GotFocus += (object anonSender, EventArgs anonE) => { txtBox.Parent.Focus(); };
  • 编辑**:代码说明
bjg7j2ky

bjg7j2ky4#

如果你子类化ListBox并覆盖OnMouseClick方法,你可能会有一些运气:

public class CustomListBox : ListBox
{
    public bool SelectionDisabled = false;

    protected override void OnMouseClick(MouseEventArgs e)
    {
        if (SelectionDisabled)
        {
            // do nothing.
        }
        else
        {
            //enable normal behavior
            base.OnMouseClick(e);
        }
    }
}

当然,你可能想做更好的信息隐藏或类设计,但这是基本的功能。您可能还需要覆盖其他方法。

wtzytmuj

wtzytmuj5#

因为提问者需要的是防止个别选项被点击,而不是全面禁用它们。
这是我的方式:

public class XCheckListBox : ListBox
{
    public XCheckListBox()
    {
        this.DrawMode = DrawMode.OwnerDrawFixed;
    }

    public Pen ForeColorPen => new Pen(ForeColor);

    [Category("Misc"), Description("是否多选"), Browsable(true), DefaultValue(false)]
    public bool MultiCheck { get => base.SelectionMode != SelectionMode.One; set => base.SelectionMode = value ? SelectionMode.MultiSimple : SelectionMode.One; }

    protected override void OnDrawItem(DrawItemEventArgs e)
    {
        if (e.Index < 0) return;

        var @checked = e.State.HasFlag(DrawItemState.Selected);
        var g = e.Graphics;
        var rectOfItem = e.Bounds;
        //g.FillRectangle(BackColorBrush, rectOfItem);//e.DrawBackground();

        //if the item state is selected them change the back color 
        if (@checked)
            e = new DrawItemEventArgs(e.Graphics,
                                      e.Font,
                                      e.Bounds,
                                      e.Index,
                                      e.State ^ DrawItemState.Selected,
                                      e.ForeColor,
                                     Color.LightSteelBlue);// SystemColors.InactiveBorder Color.Yellow  Choose the color

        // Draw the background of the ListBox control for each item.
        e.DrawBackground();

        var rectOfCheckBox = rectOfItem.CenterSquareBox().Padding(2, 2).SetX(1);
        g.DrawRectangle(ForeColorPen, rectOfCheckBox);

        var sizeBeforeText = new Size(1 + rectOfCheckBox.RightTop().X + 3, rectOfItem.Height);
        var rectOfText = new Rectangle(rectOfItem.X + sizeBeforeText.Width, rectOfItem.Y, rectOfItem.Width - sizeBeforeText.Width, rectOfItem.Height);

        var itemText = "";
        itemText = this.DesignMode ?
            this.Text
            : this.Items.Count > e.Index ?
                this.Items[e.Index]?.ToString() ?? ""
                : "";

        var cbxSize = rectOfCheckBox.Padding(3, 3);
        //CheckBoxRenderer.GetGlyphSize

        if (@checked && !DisableList.Contains(itemText))
            TextRenderer.DrawText(g, "✔", e.Font, rectOfCheckBox, this.ForeColor, TextFormatFlags.Left | TextFormatFlags.VerticalCenter);
        //ControlPaint.DrawCheckBox(e.Graphics, rectOfCheckBox, @checked ? ButtonState.Checked : ButtonState.Normal);
        ////CheckBoxRenderer.DrawCheckBox(g, cbxSize.Location, CheckBoxState.MixedNormal);

        TextRenderer.DrawText(g, itemText, e.Font, rectOfText, this.ForeColor, TextFormatFlags.Left | TextFormatFlags.VerticalCenter);

        // If the ListBox has focus, draw a focus rectangle around the selected item.
        e.DrawFocusRectangle();

    }

    protected override void OnSelectedValueChanged(EventArgs e)
    {
        var uncheckedIdx = new List<int>();
        foreach (var selectItem in this.SelectedIndices)
        {
            var ckdIdx = selectItem as int?;
            if (ckdIdx == null || ckdIdx.Value < 0) continue;
            var ckdItem = this.Items[ckdIdx.Value] as string;
            if (ckdItem == null) continue;
            if (DisableList.Contains(ckdItem))
                uncheckedIdx.Add(ckdIdx.Value);
        }

        foreach (var ckIdx in uncheckedIdx)
            this.SetSelected(ckIdx, false);

        base.OnSelectedValueChanged(e);
    }

    public void SetDisable(string item, bool enable)
    {
        if (!enable)
            DisableList.AddOrIgnore(item);
        else
            DisableList.Remove(item);

    }


    public List<string> DisableList = new List<string>();

}

public static class SharpEx
{
    public static Point AddX(this Point _this, int x) => new Point(_this.X + x, _this.Y);
    public static Point AddY(this Point _this, int y) => new Point(_this.X, _this.Y + y);

    public static Point SetX(this Point _this, int x) => new Point(x, _this.Y);
    public static Point SetY(this Point _this, int y) => new Point(_this.X, y);

    public static Point[] CenterLineInLine(this Point[] _this, decimal persent)
    {
        var poffset = (1 - persent) / 2;

        var need = poffset;
        var remain = 1 - poffset;
        var p1 = _this[0];
        var p2 = _this[1];
        var pX1 = (int)(p1.X * remain + p2.X * need);
        var pY1 = (int)(p1.Y * remain + p2.Y * need);
        var pX2 = (int)(p1.X * need + p2.X * remain);
        var pY2 = (int)(p1.Y * need + p2.Y * remain);

        return new Point[] { new Point(pX1, pY1), new Point(pX2, pY2) };
    }

    public static Size AddWidth(this Size _this, int width)
    {
        return new Size(_this.Width + width, _this.Height);
    }

    public static Size AddHeight(this Size _this, int height)
    {
        return new Size(_this.Width, _this.Height + height);
    }

    public static Size AddWidthHeight(this Size _this, int width = 0, int height = 0)
    {
        return new Size(_this.Width + width, _this.Height + height);
    }

    public static Point Start(this Rectangle _this) => _this.Location;
    public static Point End(this Rectangle _this) => _this.Location.AddX(_this.Width).AddY(_this.Height);
    public static Point LeftDown(this Rectangle _this) => _this.Location.AddY(_this.Height);
    public static Point RightTop(this Rectangle _this) => _this.Location.AddX(_this.Width);

    public static Point[] StartEnd(this Rectangle _this) => new Point[] { _this.Start(), _this.End() };

    public static Line[] XLine(this Rectangle _this, int paddingLeftRight, decimal lengthPersend) => _this.DiagonalLine(paddingLeftRight, lengthPersend);

    public static Point[] LeftDownRightTop(this Rectangle _this) => new Point[] { _this.LeftDown(), _this.RightTop() };

    public static Point[] CenterLine(this Rectangle _this, bool HorizontalOrVertical, decimal lengthPersend)
    {
        var length = (int)(HorizontalOrVertical ? lengthPersend * _this.Width : lengthPersend * _this.Height);

        if (HorizontalOrVertical)
        {
            return CenterLineInLine(new Point[]{ _this.Location.AddY(_this.Height / 2),
                _this.Location.AddX(_this.Width).AddY(_this.Height / 2) }, lengthPersend);
        }
        else
        {
            return CenterLineInLine(new Point[]{ new Point(_this.X+ _this.Width / 2, _this.Y ),
            new Point(_this.X+_this.Height / 2, _this.Y +_this.Height ) }, lengthPersend);
        }
    }

    public static Rectangle CenterSquareBox(this Rectangle _this)
    {
        if (_this.Width == _this.Height) return _this;
        var centerSquareBoxWidth = Math.Min(_this.Width, _this.Height);
        var location = _this.OffsetX((_this.Width - centerSquareBoxWidth) / 2).OffsetY((_this.Height - centerSquareBoxWidth) / 2).Location;
        return new Rectangle(location, new Size(centerSquareBoxWidth, centerSquareBoxWidth));
    }

    public static Rectangle CenterSameBox(this Rectangle _this, Size size)
    {
        var x = _this.X + (_this.Width / 2 - size.Width / 2);
        var y = _this.Y + (_this.Height / 2 - size.Height / 2);
        return new(new(x, y), size);
    }

    public static Point CenterPoint(this Rectangle _this)
    {
        var x = _this.X + _this.Width / 2;
        var y = _this.Y + _this.Height / 2;
        return new(x, y);
    }

    /// <summary>
    /// 对角线
    /// </summary>
    /// <param name="_this"></param>
    /// <param name="paddingLeftRight"></param>
    /// <param name="lengthPersend"></param>
    /// <returns></returns>
    public static Line[] DiagonalLine(this Rectangle _this, int paddingLeftRight, decimal lengthPersend)
    {
        _this = _this.Padding(paddingLeftRight);
        return new Line[] { new(_this.StartEnd().CenterLineInLine(lengthPersend)), new(_this.LeftDownRightTop().CenterLineInLine(lengthPersend)) };
    }

    public static Rectangle MarginKeepLocation(this Rectangle _this, int marginLeftRight = 0, int marginTopButtom = 0)
    {
        return _this.Padding(-marginLeftRight, -marginTopButtom).OffsetXY(marginLeftRight, marginTopButtom);
    }
    public static Rectangle Margin(this Rectangle _this, int marginLeftRight = 0, int marginTopButtom = 0)
    {
        return _this.Padding(-marginLeftRight, -marginTopButtom);
    }

    public static Rectangle Margin2(this Rectangle _this, int left = 0, int right = 0, int top = 0, int buttom = 0)
    {
        return _this.Padding2(-left, -right, top, buttom);
    }

    public static Rectangle Margin2KeepLocation(this Rectangle _this, int left = 0, int right = 0, int top = 0, int buttom = 0)
    {
        return _this.Padding2(-left, -right, top, buttom).OffsetXY(left, top);
    }

    public static Rectangle Padding(this Rectangle _this, int paddingLeftRight = 0, int paddingTopButtom = 0)
    {
        return new Rectangle(_this.Location.AddX(paddingLeftRight).AddY(paddingTopButtom),
            new Size(_this.Width - paddingLeftRight * 2, _this.Height - paddingTopButtom * 2));
    }

    public static Rectangle Padding2(this Rectangle _this, int left = 0, int right = 0, int top = 0, int buttom = 0)
    {
        return new Rectangle(_this.Location.AddX(left).AddY(top),
            new Size(_this.Width - (left + right), _this.Height - (top + buttom)));
    }

    public static Rectangle Padding(this Rectangle _this, Padding padding)
    {
        return new Rectangle(_this.Location.AddX(padding.Left).AddY(padding.Top),
            new Size(_this.Width - (padding.Left + padding.Right), _this.Height - (padding.Top + padding.Bottom)));
    }

    public static Rectangle SetX(this Rectangle _this, int setX) => new Rectangle(new Point(setX, _this.Location.Y), _this.Size);
    public static Rectangle SetY(this Rectangle _this, int setY) => new Rectangle(new Point(_this.Location.X, setY), _this.Size);

    public static Rectangle OffsetX(this Rectangle _this, int offsetX) => new Rectangle(_this.Location.AddX(offsetX), _this.Size);
    public static Rectangle OffsetY(this Rectangle _this, int offsetY) => new Rectangle(_this.Location.AddY(offsetY), _this.Size);

    public static Rectangle OffsetWidth(this Rectangle _this, int offsetWidth) => new Rectangle(_this.Location, new Size(_this.Size.Width + offsetWidth, _this.Size.Height));
    public static Rectangle OffsetHeight(this Rectangle _this, int offsetHeight) => new Rectangle(_this.Location, new Size(_this.Size.Width, _this.Size.Height + offsetHeight));

    public static Rectangle OffsetSize(this Rectangle _this, int offsetWidth, int offsetHeight) => _this.OffsetWidthHeight(offsetWidth, offsetHeight);

    public static Rectangle OffsetWidthHeight(this Rectangle _this, int offsetWidth, int offsetHeight) => new Rectangle(_this.Location, new Size(_this.Size.Width + offsetWidth, _this.Size.Height + offsetHeight));

    public static Rectangle OffsetXY(this Rectangle _this, int offsetX, int offsetY) => new Rectangle(_this.Location.AddX(offsetX).AddY(offsetY), _this.Size);

    public static Padding SetLeft(this Padding _this, int left) => new Padding(left, _this.Top, _this.Right, _this.Bottom);
    public static Padding SetTop(this Padding _this, int top) => new Padding(_this.Left, top, _this.Right, _this.Bottom);
    public static Padding SetRight(this Padding _this, int right) => new Padding(_this.Left, _this.Top, right, _this.Bottom);
    public static Padding SetBottom(this Padding _this, int bottom) => new Padding(_this.Left, _this.Top, _this.Right, bottom);

    public static Padding OffsetLeft(this Padding _this, int offsetLeft) => _this.SetLeft(_this.Left + offsetLeft);
    public static Padding OffsetTop(this Padding _this, int offsetTop) => _this.SetTop(_this.Top + offsetTop);
    public static Padding OffsetRight(this Padding _this, int offsetRight) => _this.SetRight(_this.Right + offsetRight);
    public static Padding OffsetBottom(this Padding _this, int offsetBottom) => _this.SetBottom(_this.Left + offsetBottom);

}

public struct Line
{
    public Line(int xStart, int yStart, int xEnd, int yEnd)
    {
        XStart = xStart;
        YStart = yStart;
        XEnd = xEnd;
        YEnd = yEnd;
    }

    public Line(Point start, Point end)
    {
        XStart = start.X;
        YStart = start.Y;
        XEnd = end.X;
        YEnd = end.Y;
    }

    public Line(Point[] startEnd)
    {
        XStart = startEnd[0].X;
        YStart = startEnd[0].Y;
        XEnd = startEnd[1].X;
        YEnd = startEnd[1].Y;
    }

    public int XStart;
    public int YStart;
    public int XEnd;
    public int YEnd;
    public Point Start => new Point(XStart, YStart);
    public Point End => new Point(XEnd, YEnd);

    public static implicit operator Point[](Line line)
    {
        return new Point[2] { line.Start, line.End };
    }
}

public static class ObjectEx
{

    public static ICollection<T> AddOrIgnore<T>(this ICollection<T> _this, params T[] items)
    {
        foreach (var item in items)
            if (!_this.Contains(item))
                _this.Add(item);

        return _this;
    }
}

相关问题