如何从派生的 DataGridViewColourComboBoxCell 调用 EditingControlShowing class

How to invoke EditingControlShowing from derived DataGridViewColourComboBoxCell class

所以我开始制作自己的自定义 DataGridView 列和单元格 class 从组合框派生:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Teigha.TD;

namespace TruckleSoft
{
    class DataGridViewColourComboBoxColumn : DataGridViewComboBoxColumn
    {
        public DataGridViewColourComboBoxColumn()
        {
            CellTemplate = new DataGridViewColourComboBoxCell();
            Name = "Colour";
            ValueMember = "Name";
        }

        public override DataGridViewCell CellTemplate
        {
            get
            {
                return base.CellTemplate;
            }

            set
            {
                base.CellTemplate = value;
            }
        }
    }

    class DataGridViewColourComboBoxCell : DataGridViewComboBoxCell
    {
        public DataGridViewColourComboBoxCell()
        {
            InitialiseCell();
        }

        private void InitialiseCell()
        {
            List<ushort> listColours = new List<ushort>();
            listColours.Add(1);
            listColours.Add(2);
            listColours.Add(3);
            listColours.Add(4);
            listColours.Add(5);
            listColours.Add(6);
            listColours.Add(7);
            listColours.Add(8);
            listColours.Add(9);
            listColours.Add(250);
            listColours.Add(251);
            listColours.Add(252);
            listColours.Add(253);
            listColours.Add(254);
            listColours.Add(255);

            this.Items.Clear();
            foreach (ushort iColourIndex in listColours)
                this.Items.Add(ComboboxColourItem.Create(iColourIndex));
        }

        protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
        {
            //base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);

            Color c = Color.Empty;
            string s = "";
            Brush br = SystemBrushes.WindowText;
            Brush brBack;
            Rectangle rDraw;

            rDraw = cellBounds;
            rDraw = Rectangle.FromLTRB(cellBounds.Left, cellBounds.Top, cellBounds.Right, cellBounds.Bottom - 1);

            brBack = Brushes.White;
            //Pen penGridlines = new Pen(dataGridView.GridColor);
            g.DrawRectangle(Pens.Black, rDraw);
            g.FillRectangle(brBack, rDraw);
            //penGridlines.Dispose();

            if (value != null)
            {
                ComboboxColourItem oColourItem = (ComboboxColourItem)value;
                s = oColourItem.ToString();
                c = oColourItem.Value;
            }

            if (c != Color.Empty)
            {
                SolidBrush b = new SolidBrush(c);
                Rectangle r = new Rectangle(cellBounds.Left + 6,
                                             cellBounds.Top + 5, 20, 10);
                g.FillRectangle(b, r);
                g.DrawRectangle(Pens.Black, r);
                g.DrawString(s, Form.DefaultFont, Brushes.Black,
                             cellBounds.Left + 35, cellBounds.Top + 3);

                b.Dispose();
            }

            int butSize = cellBounds.Height;
            Rectangle rbut = new Rectangle(cellBounds.Right - butSize,
                                           cellBounds.Top, butSize, butSize);
            ComboBoxRenderer.DrawDropDownButton(graphics, rbut,
                       System.Windows.Forms.VisualStyles.ComboBoxState.Normal);
        }

        private void ColourComboBox_DrawItem(object sender, DrawItemEventArgs e)
        {
            Graphics g = e.Graphics;
            Color c = Color.Empty;
            string s = "";
            Brush br = SystemBrushes.WindowText;
            Brush brBack;
            Rectangle rDraw;
            bool bSelected = Convert.ToBoolean(e.State & DrawItemState.Selected);
            bool bValue = Convert.ToBoolean(e.State & DrawItemState.ComboBoxEdit);

            rDraw = e.Bounds;
            rDraw.Inflate(-1, -1);

            if (bSelected & !bValue)
            {
                brBack = Brushes.LightBlue;
                g.FillRectangle(Brushes.LightBlue, rDraw);
                g.DrawRectangle(Pens.Blue, rDraw);
            }
            else
            {
                brBack = Brushes.White;
                g.FillRectangle(brBack, e.Bounds);
            }

            try
            {
                ComboboxColourItem oColourItem = (ComboboxColourItem)((ComboBox)sender).Items[e.Index];
                s = oColourItem.ToString();
                c = oColourItem.Value;
            }
            catch
            {
                //s = "red";
                //c = Color.Red;
            }

            if (c != Color.Empty)
            {
                SolidBrush b = new SolidBrush(c);
                Rectangle r = new Rectangle(e.Bounds.Left + 5, e.Bounds.Top + 3, 20, 10);
                g.FillRectangle(b, r);
                g.DrawRectangle(Pens.Black, r);
                g.DrawString(s, Form.DefaultFont, Brushes.Black, e.Bounds.Left + 35, e.Bounds.Top + 1);

                b.Dispose();
            }

            //g.Dispose();
        }

    }

    public class ComboboxColourItem
    {
        public string Name { get; set; }
        public ushort Index { get; set; }
        public Color Value { get; set; }

        public ComboboxColourItem(string Name, ushort Index, Color Value)
        {
            this.Name = Name;
            this.Index = Index;
            this.Value = Value;
        }
        public override string ToString()
        {
            return Name;
        }

        static public ComboboxColourItem Create(ushort iColourIndex)
        {
            OdCmColor oColour = new OdCmColor();

            oColour.setColorIndex(iColourIndex);

            CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;
            TextInfo textInfo = cultureInfo.TextInfo;

            String strColour = textInfo.ToTitleCase(oColour.colorNameForDisplay());
            if (iColourIndex < 8)
                strColour = String.Format("{0} ({1})", strColour, iColourIndex);
            else if (iColourIndex == 8 || iColourIndex == 9 || iColourIndex >= 250)
                strColour = String.Format("Grey Shade ({0})", iColourIndex);
            else
                strColour = String.Format("Other ({0})", iColourIndex);
            ComboboxColourItem oColourItem = new ComboboxColourItem(
                strColour,
                iColourIndex,
                Color.FromArgb(oColour.red(), oColour.green(), oColour.blue()));

            oColour.Dispose();

            return oColourItem;
        }
    }
}

我现在遇到的问题是:

private void DataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
    if (e.Control is ComboBox)
    {
        ComboBox theCB = (ComboBox)e.Control;
        theCB.DrawMode = DrawMode.OwnerDrawFixed;
        try
        {
            theCB.DrawItem -= new DrawItemEventHandler(this.combobox1_DrawItem);
        }
        catch { }
        theCB.DrawItem += new DrawItemEventHandler(this.combobox1_DrawItem);
    }
}

以上是DataGridView对象的处理函数。如何在我的 DataGridViewColourComboBoxCell class 中复制它?应该是class规定了DrawItem方法

更新:

我知道我还需要制作自己的编辑控件并执行以下操作:

public override Type EditType
{
    get
    {
        return typeof(DataGridViewColourComboBoxEditingControl);
    }
}

然后我补充说:

    protected override void OnDrawItem(DrawItemEventArgs e)
    {
        //base.OnDrawItem(e);

        Graphics g = e.Graphics;
        Color c = Color.Empty;
        string s = "";
        Brush br = SystemBrushes.WindowText;
        Brush brBack;
        Rectangle rDraw;
        bool bSelected = Convert.ToBoolean(e.State & DrawItemState.Selected);
        bool bValue = Convert.ToBoolean(e.State & DrawItemState.ComboBoxEdit);

        rDraw = e.Bounds;
        rDraw.Inflate(-1, -1);

        if (bSelected & !bValue)
        {
            brBack = Brushes.LightBlue;
            g.FillRectangle(Brushes.LightBlue, rDraw);
            g.DrawRectangle(Pens.Blue, rDraw);
        }
        else
        {
            brBack = Brushes.White;
            g.FillRectangle(brBack, e.Bounds);
        }

        try
        {
            ComboboxColourItem oColourItem = (ComboboxColourItem)Items[e.Index];
            s = oColourItem.ToString();
            c = oColourItem.Value;
        }
        catch
        {
            //s = "red";
            //c = Color.Red;
        }

        if (c != Color.Empty)
        {
            SolidBrush b = new SolidBrush(c);
            Rectangle r = new Rectangle(e.Bounds.Left + 5, e.Bounds.Top + 3, 20, 10);
            g.FillRectangle(b, r);
            g.DrawRectangle(Pens.Black, r);
            g.DrawString(s, Form.DefaultFont, Brushes.Black, e.Bounds.Left + 35, e.Bounds.Top + 1);

            b.Dispose();
        }
    }
}

所以我现在还有的问题是:

在单元格 Paint 事件中:

protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)

我做不到:

//Pen penGridlines = new Pen(dataGridView.GridColor);

因为我们在单元格对象中。

此外,这是否相当于 "CellParsing":

public override object ParseFormattedValue(object formattedValue, DataGridViewCellStyle cellStyle, TypeConverter formattedValueTypeConverter, TypeConverter valueTypeConverter)
{
    return base.ParseFormattedValue(formattedValue, cellStyle, formattedValueTypeConverter, valueTypeConverter);
}

这对我很有帮助:

http://www.codeproject.com/Articles/15827/Gain-Access-To-DataGridView-Canned-Controls

我必须从 DataGridViewComboBoxEditingControl 创建一个新的派生 class 并在该对象中将其设置为 ownerdraw 并处理 OnDrawItem 事件。

DataGridViewColourComboBoxCell class 我不得不覆盖 EditType 属性:

public override Type EditType
{
    get
    {
        return typeof(DataGridViewColourComboBoxEditingControl);
    }
}

对于 CellParsing 我确实必须覆盖 ParseFormattedValue.