【问题标题】:Can I disable a combobox in WinForms without graying it out?我可以在 WinForms 中禁用组合框而不使其变灰吗?
【发布时间】:2011-07-27 08:12:16
【问题描述】:

有没有办法禁用组合框的值更改而不会在 Windows 窗体中变灰?我看到了一些帖子,但它们是针对 WPF 的,对我的情况没有帮助。

【问题讨论】:

  • 所以你想要一个看起来很正常但用户无法与之交互的组合框?你将如何向用户表明它处于这种不可用状态?
  • 这是一个非常糟糕的主意。使组合框变灰是用户知道它被禁用并且他们无法修改它的方式。 看起来启用的组合框,但忽略了用户对其进行编辑的尝试,这简直令人困惑。我会称该接口为 broken
  • 如果用户无法更改,为什么要使用组合框?它应该是一个标签。组合框意味着选择。 (而且客户并不总是正确的 - 有时他们只是缺乏教育,而提供教育可能是您工作的一部分。)
  • 嗯,我建议强烈重新考虑这是否是一个好主意的原因是因为它不是很容易实现。您必须对整个控件进行所有者绘制。这是可能的,但由于已经提到的原因,Windows 并不容易。作为程序员,你的工作是向客户解释他们所要求的内容有什么问题。他们可能没有意识到这一点;其他人之前已经为他们处理过这个决定。但是,一旦他们得到原型,他们就会发现要弄清楚框何时可编辑以及何时不可编辑是多么困难。
  • @Cody 同意,但有时当您在问题中添加一些管理 + 客户 + 预算 + 公司时,这实际上是不可能的。在我过去的一次经验中,我们必须实现一个下拉菜单,如果(技术上不是下拉 shoot side),我们必须实现一个水平拍摄,原因是客户正在评估我们的交付能力并且我们正在启动,并且需要做任何事情。

标签: c# .net winforms combobox controls


【解决方案1】:

在您的comobobox 上设置这些将达到您想要的效果,Combo 已启用,但没有人可以更改或输入任何内容,因此 Appearance = Enabled,Behavior = Disabled :)

        comboBox1.DropDownHeight = 1;
        comboBox1.KeyDown += (s, e) => e.Handled = true;
        comboBox1.KeyPress += (s, e) => e.Handled = true;
        comboBox1.KeyUp += (s, e) => e.Handled = true;

如果由于某种原因您不能使用 lambda,则可以关联以下处理程序。右键单击 -> 如果您有 DropDownStyle = DropDown,则必须另外处理粘贴。

    //void comboBox1_KeyUp(object sender, KeyEventArgs e)
    //{
    //    e.Handled = true;
    //}

    //void comboBox1_KeyPress(object sender, KeyPressEventArgs e)
    //{
    //    e.Handled = true;
    //}

    //void comboBox1_KeyDown(object sender, KeyEventArgs e)
    //{
    //    e.Handled = true;
    //}

【讨论】:

  • 如果我使用鼠标会发生什么?
  • 重新启用而不是true;使用 bool 变量将您的启用/禁用状态存储在 lambda 或事件处理程序中。并将 DropDownHeight 设置为 100 或 200 之类的看起来不错的值。 e.Handled = someBoolVar; 而不是 e.Handled = true;
  • @Sanjeevakumar:嗯,是的。组合框仍然可以获取焦点,我仍然可以通过旋转滚轮来更改所选项目。
  • 我测试了轮子旋转,它不让我选择,你能用一些临时位置分享你的代码吗,
  • 要禁用Paste,您可以创建一个假的空上下文菜单并将其分配给组合框。
【解决方案2】:

然后将他的处理程序保存为变量,然后简单地 -= 它们。

例子:

var keyDown = (s, e) => e.Handled = true;
var keyPress = (s, e) => e.Handled = true;
var keyUp = (s, e) => e.Handled = true;

然后在他的替换为:

comboBox1.KeyDown += keyDown;
comboBox1.KeyPress += keyPress;
comboBox1.KeyUp += keyUp;

那么当你要删除时:

comboBox1.KeyDown -= keyDown;
comboBox1.KeyPress -= keyPress;
comboBox1.KeyUp -= keyUp;

【讨论】:

  • 不是用var那么简单,用Sanjeevakumar的方法和-=那些。
  • 或者使用e.Handled = someBoolVar,其中 someBoolVar 的状态为启用/禁用。
  • 如何重置 DropDownHeight 的高度?我应该最初存储高度吗?并在我想重新启用时将其重置为?
  • 你可以这样做或者创建一个包含很多项目的组合,然后看看最大值是多少; DropDownHeight 设置为那个。
【解决方案3】:

在 GotFocus 处理程序(无论它叫什么)中,将焦点设置为其他内容。

【讨论】:

    【解决方案4】:

    不,还不够好。将其禁用并看起来完全像原来的那样,这样用户就完全被愚弄了。添加一个新类并粘贴此代码。

    using System;
    using System.Drawing;
    using System.Windows.Forms;
    
    class FakeComboBox : ComboBox {
        private PictureBox fake;
        public new bool Enabled {
            get { return base.Enabled; }
            set { if (!this.DesignMode) displayFake(value);
                  base.Enabled = value;
            }
        }
        private void displayFake(bool enabled) {
            if (!enabled) {
                fake = new PictureBox();
                fake.Location = this.Location;
                fake.Size = this.Size;
                var bmp = new Bitmap(fake.Size.Width, fake.Size.Height);
                this.DrawToBitmap(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height));
                fake.Image = bmp;
                this.Parent.Controls.Add(fake);
                fake.BringToFront();
                fake.Click += delegate { Console.Beep(); };
            }
            else {
                this.Parent.Controls.Remove(fake);
                fake.Dispose();
                fake = null;
            }
        }
    }
    

    当您重新启用 Win7 时,您在 Win7 上看到的非常轻微的“发光”非常有趣。

    【讨论】:

    • 哈哈,太棒了。尽管这很荒谬,但它仍然是比将 DropDownHeight 设置为 0 更好的解决方案。
    • 启用此控件后,您尝试再次设置启用。此代码尝试处理为空的fake。并抛出异常。其次,它看起来仍然是灰色的,如果它必须看起来像一个启用的组合,则必须处理任何主题更改。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-22
    • 2019-01-08
    • 2021-05-20
    • 1970-01-01
    • 1970-01-01
    • 2019-09-15
    • 1970-01-01
    相关资源
    最近更新 更多