【问题标题】:Combobox DropDownList Style with white background白色背景的组合框下拉列表样式
【发布时间】:2016-07-30 22:40:37
【问题描述】:

我想要一个不可编辑的 ComboBox 但仍显示白色背景颜色,因此它的样式与默认 ComboBox 样式 (DropDown) 类似。 ComboBoxStyle.DropDownList 仅提供标准的“禁用”灰色背景颜色。简单地设置 BackColor = Color.White 没有任何效果。

下拉列表:

下拉:

【问题讨论】:

标签: c# combobox


【解决方案1】:

要使 ComboBox DropDownList 看起来像 ComboBox DropDown:

  1. 将组合框添加到 WinForm。转到属性资源管理器。选择 DropDownStyle > DropDownList。然后选择 FlatStyle > Flat。
  2. 将面板添加到 WinForm。转到属性资源管理器。选择 BorderStyle > FixedSingle。
  3. 将组合框拖到面板上。激活 ComboBox 后,转到 Properties Explorer > Dock > Fill。
  4. 在 ComboBox 处于活动状态时,按住“Shift”键,选择面板以使其也处于活动状态(选择顺序很重要)。
  5. 转到布局工具栏(视图 > 工具栏 > 布局)并选择“制作相同大小”。
  6. 运行程序时,DropDownList ComboBox 应该看起来像 DropDown ComboBox

【讨论】:

  • 当“Dock = Fill”应该做同样的事情时,为什么还需要“Make Same Size”?
【解决方案2】:

要实现一个带有白色背景的 DropDownList 组合框,请创建一个简单的包装类:

  public class ComboBoxClean : ComboBox
    {
        public ComboBoxClean()
        {
            DropDownStyle = ComboBoxStyle.DropDownList;
            DrawMode = DrawMode.OwnerDrawFixed;
        }

        protected override void OnDrawItem(DrawItemEventArgs e)
        {
            Color textColor = e.ForeColor;

            if ((e.State & DrawItemState.Focus) != DrawItemState.Focus)
                e.DrawBackground();
            else
                textColor = Color.Black;

            e.DrawFocusRectangle();

            var index = e.Index;
            if (index < 0 || index >= Items.Count) return;
            var item = Items[index];

            string text = (item == null) ? "(null)" : item.ToString();
            using (var brush = new SolidBrush(textColor))
            {
                e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
                e.Graphics.DrawString(text, e.Font, brush, e.Bounds);
            }
        }
    }

【讨论】:

  • 这绝对是解决这个问题的最佳方式,但是,按照编码,突出显示条目的文本颜色是黑色(在蓝色背景上),而不是应有的白色。我是处理绘图的新手,所以我想弄清楚如何解决这个问题。
  • @technonaut,删除检查 if ((e.State &amp; DrawItemState.Focus) != DrawItemState.Focus) 和设置 textColor = Color.Black;。这对我有用。
【解决方案3】:

我玩了一段时间,不想做任何涉及太多的事情。以上这些想法可能有效,但我所做的只是将 flatStyle 属性从“标准”更改为“平面”。

虽然不完美,但它至少将灰色/禁用外观的背景更改为白色。

你可以在这里看到比较:

加热源 #1 > DropdownList > flat(下拉列表后的最终决定是允许用户输入错误数据)

Heater Source #2 > Dropdown > Standard(默认的看起来不错)

房屋类型 > 下拉菜单 > 平房

Heating Source #1 Vendor > DropdownList > Standard(默认为禁用的 gray

【讨论】:

    【解决方案4】:

    我看到这篇文章正在寻找解决这个问题的方法,但找不到正是我需要的解决方案。我进行了一些试验,并提出了适用于 Visual Basic .NET 的解决方案,该解决方案融合了本文中 Adam 的代码和其他 here 的代码。

    我将展示两种不同的方法,并简要讨论优点和缺点:

    1. 挂钩 DrawItem 事件;
    2. 创建自定义控件。

    =============================方法1 ================= ===============

    此方法只是简单地挂钩 ComboBox 的 DrawItem 事件,因此不需要自定义控件。

    第 1 步

    像往常一样添加您的 ComboBox。在其属性中,将 DrawMode 更改为 OwnerDrawFixed。如果你忘记了这一点,下一部分将无济于事。当然,也可以将您的 DropDownStyle 更改为 DropDownList

    第 2 步

    添加自定义处理程序:

    Private Sub ComboBox1_DrawItem(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles ComboBox1.DrawItem
        Dim cmb = CType(sender, ComboBox)
        If cmb Is Nothing Then Return
    
        Dim index As Integer = If(e.Index >= 0, e.Index, -1)
        Dim brush As Brush = If(((e.State And DrawItemState.Selected) > 0), SystemBrushes.HighlightText, New SolidBrush(cmb.ForeColor))
        e.DrawBackground()
    
        If index <> -1 Then
            e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit
            e.Graphics.DrawString(cmb.Items(index).ToString(), e.Font, brush, e.Bounds, StringFormat.GenericDefault)
        End If
    
        e.DrawFocusRectangle()
    End Sub
    

    注意

    您可以使用单个 sub 来处理多个 ComboBox,但您必须记住手动将它们添加到 Handles

    =============================方法2 ================= ===============

    此方法依赖于从 ComboBox 继承的自定义控件。通过将这个自定义控件添加到我们的表单中,而不是普通的 ComboBox,它就可以工作了——我们不必担心Handles 语句。如果您打算拥有多个 ComboBox,这可能是可行的方法。

    第 1 步

    通过右键单击您的项目添加自定义控件,添加,新建项目,然后选择自定义控件(Windows 窗体)。我将我的命名为 ComboBoxClean

    第 2 步

    在文件 ComboBoxClean.vb 中,将自动生成的代码替换为:

    Public Class ComboBoxClean
        Inherits ComboBox
    
        Public Sub New()
            DropDownStyle = ComboBoxStyle.DropDownList
            DrawMode = DrawMode.OwnerDrawFixed
        End Sub
    
        Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
            MyBase.OnPaint(e)
        End Sub
    
        Protected Overrides Sub OnDrawItem(ByVal e As DrawItemEventArgs)
            Dim index As Integer = If(e.Index >= 0, e.Index, -1)
            Dim brush As Brush = If(((e.State And DrawItemState.Selected) > 0), SystemBrushes.HighlightText, New SolidBrush(ForeColor))
            e.DrawBackground()
    
            If index <> -1 Then
                e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit
                e.Graphics.DrawString(Items(index).ToString(), e.Font, brush, e.Bounds, StringFormat.GenericDefault)
            End If
    
            e.DrawFocusRectangle()
        End Sub
    End Class
    

    第 3 步

    在解决方案资源管理器中,单击显示所有文件。打开 ComboBoxClean.Designer.vb

    用这个替换现有的 Inherits 语句:

    Inherits ComboBox

    注意事项

    • 您应该在尝试使用它之前继续构建,以确保一切正常。
    • 在工具箱中,您的自定义控件将在普通控件列表中。您当前的解决方案应该在那里有自己的组件部分,您应该在其中找到新控件。只需将其拖到表单上,然后像使用普通组合框一样使用它。
    • New 会自动为我们进行重要的属性更改,否则我们每次添加新的 ComboBox 时都必须手动进行。

    【讨论】:

      【解决方案5】:

      在努力使控件看起来与 DropDown ComboBox 样式相同时,我不得不通过覆盖 OnKeyPress 事件来解决,这样它就限制了用户能够编辑控件。作为旁注,我还建议覆盖适当的事件以防止用户将值粘贴到 ComboBox (how to disable copy, Paste and delete features on a textbox using C#)。

      protected override void OnKeyPress(KeyPressEventArgs e)
      {
          e.Handled = true;
      }
      

      【讨论】:

      • 您还必须防止右键单击,因为您可以在其中剪切/粘贴并以这种方式进行编辑
      【解决方案6】:

      您必须使用 custom drawing 创建自己的 ComboBox 或使用第三方控件,例如 Infragistics UltraCombo

      public class MyComboBox : ComboBox
          {
              public MyComboBox()
              {
                  this.SetStyle(ControlStyles.UserPaint, true);
              }
      
              protected override void OnPaint(PaintEventArgs e)
              {
                // Repaint here
              }
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-12-27
        • 2019-11-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多