尘缘丶 发表于 2024-4-9 11:11

Winform自定义ComboBox控件下拉字异常

ComboBox.Text有值的时候下拉列表字显示空白,但点击后又能带入真实的值到Text文本框内
                         空的时候下拉列表字显示的是自定义PlaceHolder内容


下面上自定义控件代码,我这是用类直接写的(AI写的)。。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace EnableIE
{
    public class PlaceHolderComboBox : ComboBox
    {
      private string _placeHolder;

      /// <summary>
      /// 占位符文本
      /// </summary>
      public string PlaceHolder
      {
            get { return _placeHolder; }
            set
            {
                _placeHolder = value;
                if (string.IsNullOrEmpty(Text))
                  Text = _placeHolder;
            }
      }

      public PlaceHolderComboBox()
      {
            // 设置绘制模式为固定大小的所有者绘制
            DrawMode = DrawMode.OwnerDrawFixed;

            // 设置背景色为白色
            BackColor = Color.White;

            // 设置前景色为Bold
            this.ForeColor = SystemColors.GradientActiveCaption;
            this.Font = new Font(this.Font, FontStyle.Bold);
      }

      /// <summary>
      /// 在 ComboBox 中绘制项时调用。
      /// </summary>
      /// <param name="e">绘制项事件参数</param>
      protected override void OnDrawItem(DrawItemEventArgs e)
      {
            // 如果索引小于 0,则返回
            if (e.Index < 0)
                return;

            // 如果文本框为空且占位符不为空
            if (string.IsNullOrEmpty(Text) && !string.IsNullOrEmpty(_placeHolder))
            {
                // 绘制占位符文本
                e.Graphics.DrawString(_placeHolder, Font, new SolidBrush(ForeColor), e.Bounds.X, e.Bounds.Y);
            }
            else
            {
                // 否则绘制标准的 ComboBox 项
                base.OnDrawItem(e);
            }
      }

      /// <summary>
      /// 在文本框文本更改时调用。
      /// </summary>
      /// <param name="e">事件参数</param>
      protected override void OnTextChanged(EventArgs e)
      {
            // 调用基类的文本更改事件处理程序
            base.OnTextChanged(e);

            // 如果文本框为空
            if (string.IsNullOrEmpty(Text))
            {
                // 设置文本框文本为占位符
                //Text = _placeHolder;
            }
      }

      /// <summary>
      /// 在文本框获得焦点时调用。
      /// </summary>
      /// <param name="e">事件参数</param>
      protected override void OnGotFocus(EventArgs e)
      {
            // 调用基类的获取焦点事件处理程序
            base.OnGotFocus(e);

            // 如果文本框文本为占位符
            if (Text == _placeHolder)
            {
                // 清空文本框文本
                base.Text = "";
                this.ForeColor = SystemColors.GradientActiveCaption;
                this.Font = new Font(this.Font, FontStyle.Bold);
            }
      }

      /// <summary>
      /// 在文本框失去焦点时调用。
      /// </summary>
      /// <param name="e">事件参数</param>
      protected override void OnLostFocus(EventArgs e)
      {
            // 调用基类的失去焦点事件处理程序
            base.OnLostFocus(e);

            // 如果文本框为空或文本框文本为占位符
            if (string.IsNullOrEmpty(Text) || Text == _placeHolder)
            {
                // 设置文本框文本为占位符
                Text = _placeHolder;
                this.ForeColor = Color.Gray;
                this.Font = new Font(this.Font, FontStyle.Regular);
            }
      }
    }
}

gtsarman5 发表于 2024-4-9 13:03

flyer_2001 发表于 2024-4-9 16:33


if (string.IsNullOrEmpty(Text))
      Text = _placeHolder;
// 这个判断反掉了

flyer_2001 发表于 2024-4-9 17:19

flyer_2001 发表于 2024-4-9 16:33

if (string.IsNullOrEmpty(Text))
      Text = _placeHolder;


理解错了,请无视

flyer_2001 发表于 2024-4-9 19:27

本帖最后由 flyer_2001 于 2024-4-9 21:16 编辑

protected override void OnDrawItem(DrawItemEventArgs e)

这里的判断有问题
改成
            // 如果文本框为空且占位符不为空
            if ( !string.IsNullOrEmpty(_placeHolder))
            {
                // 绘制占位符文本
                e.Graphics.DrawString(_placeHolder, Font, new SolidBrush(ForeColor), e.Bounds.X, e.Bounds.Y);
            }
            else
            {
                // 否则绘制标准的 ComboBox 项
                base.OnDrawItem(e);
            }

尘缘丶 发表于 2024-4-9 22:29

flyer_2001 发表于 2024-4-9 19:27
这 ...

解决办法是不判断文本框或占位符是否为空,直接绘制items.ToString();
代码如下:// 绘制标准的 ComboBox 项
                e.DrawBackground();
                e.Graphics.DrawString(item.ToString(), Font, new SolidBrush(ForeColor), e.Bounds.X, e.Bounds.Y);
                e.DrawFocusRectangle();
页: [1]
查看完整版本: Winform自定义ComboBox控件下拉字异常