Implementing a Custom ComboBox into a DataGridView Column

I recently created a custom combo box with a button and now I am trying to create a data grid view column that uses that control. I have tried a few different methods including trying to build the new control inside a custom editing control. I have been able to get the control to show but the Button does not paint correctly nor is it clickable. The drop down won’t show. and if I click the drop down arrow while the control is showing I get a null reference error in the protected override void WndProc(ref Message m).

The Idea for this control is to be able to click the button within the combobox to add items to the datasource. The ComboBoxWithButton Control works perfectly on it’s own but once I try to host it in a datagridview cell everything stops working.

Here is the control I want to host in the datagridview

`

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>public class ComboBoxWithButton : ComboBox
{
private static int DROPDOWNBUTTON_WIDTH = 17;
private static int BUTTON_WIDTH = 17;
private Button customButton;
Button CustomButton
{
get
{
if (customButton == null)
{
customButton = new Button()
{
Text = ButtonText,
FlatStyle = ButtonFlatStyle,
Parent = this,
TextAlign = ButtonTextAlign,
TextImageRelation = ButtonTextImageRelation
};
customButton.FlatAppearance.BorderSize = 0;
}
customButton.SizeChanged += CustomButton_SizeChanged;
return customButton;
}
}
private void CustomButton_SizeChanged(object sender, EventArgs e)
{
BUTTON_WIDTH = customButton.Width;
}
[Browsable(true), Description("Occurs when the component is clicked."), Category("Button")]
[DisplayName("Click")]
public event EventHandler<EventArgs> ButtonClicked;
[Browsable(true), Description("The button text associated with the control"), Category("Button")]
[DisplayName("Text")]
[DefaultValue("?")]
public string ButtonText
{
get
{
if (customButton == null)
{
return GetDefaultValue<string>(this, "ButtonText");
}
else
{
return customButton.Text;
}
}
set { customButton.Text = value; }
}
[Browsable(true), Description("Determines the appearance of the control when a user moves the mouse over the control and clicks."), Category("Button")]
[DisplayName("FlatStyle")]
[DefaultValue(FlatStyle.Flat)]
public FlatStyle ButtonFlatStyle
{
get
{
if (customButton == null)
{
return GetDefaultValue<FlatStyle>(this, "ButtonFlatStyle");
}
else
{
return customButton.FlatStyle;
}
}
set { customButton.FlatStyle = value; }
}
[Browsable(true), Description("The alignment of the text that will be displayed on the control."), Category("Button")]
[DisplayName("TextAlign")]
[DefaultValue(System.Drawing.ContentAlignment.MiddleCenter)]
public System.Drawing.ContentAlignment ButtonTextAlign
{
get
{
if (customButton == null)
{
return GetDefaultValue<System.Drawing.ContentAlignment>(this, "ButtonTextAlign");
}
else
{
return customButton.TextAlign;
}
}
set { customButton.TextAlign = value; }
}
[Browsable(true), Description("Specifies the relative location of the image to the text on the button."), Category("Button")]
[DisplayName("TextImageRelation")]
[DefaultValue(TextImageRelation.Overlay)]
public TextImageRelation ButtonTextImageRelation
{
get
{
if (customButton == null)
{
return GetDefaultValue<TextImageRelation>(this, "ButtonTextImageRelation");
}
else
{
return customButton.TextImageRelation;
}
}
set { customButton.TextImageRelation = value; }
}
[Browsable(true), Description("The button image associated with the control"), Category("Button")]
[DisplayName("Image")]
public Image ButtonImage
{
get
{
if (customButton == null)
{
return GetDefaultValue<Image>(this, "ButtonImage");
}
else
{
return customButton.Image;
}
}
set { customButton.Image = value; }
}
[Browsable(true), Description("Indicates if the button associated with the control is always visable"), Category("Button")]
[DisplayName("ButtonAlwaysVisible")]
[DefaultValue(false)]
public bool ButtonAlwaysVisible { get; set; }
static T GetDefaultValue<T>(object obj, string propertyName)
{
if (obj == null) return default(T);
var prop = obj.GetType().GetProperty(propertyName);
if (prop == null) return default(T);
var attr = prop.GetCustomAttributes(typeof(DefaultValueAttribute), true);
if (attr.Length != 1) return default(T);
return (T)((DefaultValueAttribute)attr[0]).Value;
}
public ComboBoxWithButton()
{
CustomButton.Click += CustomButton_Click;
}
[DefaultValue(8)]
protected internal int EditControlOffset { get; set; } = 4;
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
UpdateControlsPosition();
}
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
switch (m.Msg)
{
case NativeMethods.WM_WINDOWPOSCHANGED:
UpdateControlsPosition();
break;
case NativeMethods.WM_DESTROY:
if (customButton != null)
{
customButton.Click -= CustomButton_Click;
customButton.Dispose();
}
break;
}
}
private void UpdateControlsPosition()
{
if (customButton != null)
{
SuspendLayout();
Rectangle arrowRect = NativeMethods.GetComboBoxInfoInternal(Handle, out Rectangle editRect, out IntPtr editHwnd);
if (arrowRect.IsEmpty || editRect.IsEmpty) return;
// Same size as the Arrow Button: change as required
DROPDOWNBUTTON_WIDTH = arrowRect.Width;
customButton.Size = arrowRect.Size;
customButton.Location = new Point(arrowRect.Left - customButton.Width - 1, 1);
editRect.Width = ClientSize.Width - customButton.Width * 2 - EditControlOffset;
NativeMethods.SetWindowPos(editHwnd, IntPtr.Zero, 0, 0, editRect.Width, editRect.Height, NativeMethods.SWP_Flags);
ResumeLayout(false);
}
}
private void CustomButton_Click(object sender, EventArgs e) => OnEditButtonClicked(e);
protected virtual void OnEditButtonClicked(EventArgs e)
{
ButtonClicked?.Invoke(this, e);
}
internal static Rectangle GetComboArrowBounds(Rectangle bounds)
{
return new Rectangle(bounds.Right - DROPDOWNBUTTON_WIDTH, bounds.Top, DROPDOWNBUTTON_WIDTH, bounds.Height);
}
internal static Rectangle GetComboButtonBounds(Rectangle bounds)
{
return new Rectangle(bounds.Right - BUTTON_WIDTH - BUTTON_WIDTH, bounds.Top, BUTTON_WIDTH, bounds.Height);
}
}
</code>
<code>public class ComboBoxWithButton : ComboBox { private static int DROPDOWNBUTTON_WIDTH = 17; private static int BUTTON_WIDTH = 17; private Button customButton; Button CustomButton { get { if (customButton == null) { customButton = new Button() { Text = ButtonText, FlatStyle = ButtonFlatStyle, Parent = this, TextAlign = ButtonTextAlign, TextImageRelation = ButtonTextImageRelation }; customButton.FlatAppearance.BorderSize = 0; } customButton.SizeChanged += CustomButton_SizeChanged; return customButton; } } private void CustomButton_SizeChanged(object sender, EventArgs e) { BUTTON_WIDTH = customButton.Width; } [Browsable(true), Description("Occurs when the component is clicked."), Category("Button")] [DisplayName("Click")] public event EventHandler<EventArgs> ButtonClicked; [Browsable(true), Description("The button text associated with the control"), Category("Button")] [DisplayName("Text")] [DefaultValue("?")] public string ButtonText { get { if (customButton == null) { return GetDefaultValue<string>(this, "ButtonText"); } else { return customButton.Text; } } set { customButton.Text = value; } } [Browsable(true), Description("Determines the appearance of the control when a user moves the mouse over the control and clicks."), Category("Button")] [DisplayName("FlatStyle")] [DefaultValue(FlatStyle.Flat)] public FlatStyle ButtonFlatStyle { get { if (customButton == null) { return GetDefaultValue<FlatStyle>(this, "ButtonFlatStyle"); } else { return customButton.FlatStyle; } } set { customButton.FlatStyle = value; } } [Browsable(true), Description("The alignment of the text that will be displayed on the control."), Category("Button")] [DisplayName("TextAlign")] [DefaultValue(System.Drawing.ContentAlignment.MiddleCenter)] public System.Drawing.ContentAlignment ButtonTextAlign { get { if (customButton == null) { return GetDefaultValue<System.Drawing.ContentAlignment>(this, "ButtonTextAlign"); } else { return customButton.TextAlign; } } set { customButton.TextAlign = value; } } [Browsable(true), Description("Specifies the relative location of the image to the text on the button."), Category("Button")] [DisplayName("TextImageRelation")] [DefaultValue(TextImageRelation.Overlay)] public TextImageRelation ButtonTextImageRelation { get { if (customButton == null) { return GetDefaultValue<TextImageRelation>(this, "ButtonTextImageRelation"); } else { return customButton.TextImageRelation; } } set { customButton.TextImageRelation = value; } } [Browsable(true), Description("The button image associated with the control"), Category("Button")] [DisplayName("Image")] public Image ButtonImage { get { if (customButton == null) { return GetDefaultValue<Image>(this, "ButtonImage"); } else { return customButton.Image; } } set { customButton.Image = value; } } [Browsable(true), Description("Indicates if the button associated with the control is always visable"), Category("Button")] [DisplayName("ButtonAlwaysVisible")] [DefaultValue(false)] public bool ButtonAlwaysVisible { get; set; } static T GetDefaultValue<T>(object obj, string propertyName) { if (obj == null) return default(T); var prop = obj.GetType().GetProperty(propertyName); if (prop == null) return default(T); var attr = prop.GetCustomAttributes(typeof(DefaultValueAttribute), true); if (attr.Length != 1) return default(T); return (T)((DefaultValueAttribute)attr[0]).Value; } public ComboBoxWithButton() { CustomButton.Click += CustomButton_Click; } [DefaultValue(8)] protected internal int EditControlOffset { get; set; } = 4; protected override void OnHandleCreated(EventArgs e) { base.OnHandleCreated(e); UpdateControlsPosition(); } protected override void WndProc(ref Message m) { base.WndProc(ref m); switch (m.Msg) { case NativeMethods.WM_WINDOWPOSCHANGED: UpdateControlsPosition(); break; case NativeMethods.WM_DESTROY: if (customButton != null) { customButton.Click -= CustomButton_Click; customButton.Dispose(); } break; } } private void UpdateControlsPosition() { if (customButton != null) { SuspendLayout(); Rectangle arrowRect = NativeMethods.GetComboBoxInfoInternal(Handle, out Rectangle editRect, out IntPtr editHwnd); if (arrowRect.IsEmpty || editRect.IsEmpty) return; // Same size as the Arrow Button: change as required DROPDOWNBUTTON_WIDTH = arrowRect.Width; customButton.Size = arrowRect.Size; customButton.Location = new Point(arrowRect.Left - customButton.Width - 1, 1); editRect.Width = ClientSize.Width - customButton.Width * 2 - EditControlOffset; NativeMethods.SetWindowPos(editHwnd, IntPtr.Zero, 0, 0, editRect.Width, editRect.Height, NativeMethods.SWP_Flags); ResumeLayout(false); } } private void CustomButton_Click(object sender, EventArgs e) => OnEditButtonClicked(e); protected virtual void OnEditButtonClicked(EventArgs e) { ButtonClicked?.Invoke(this, e); } internal static Rectangle GetComboArrowBounds(Rectangle bounds) { return new Rectangle(bounds.Right - DROPDOWNBUTTON_WIDTH, bounds.Top, DROPDOWNBUTTON_WIDTH, bounds.Height); } internal static Rectangle GetComboButtonBounds(Rectangle bounds) { return new Rectangle(bounds.Right - BUTTON_WIDTH - BUTTON_WIDTH, bounds.Top, BUTTON_WIDTH, bounds.Height); } } </code>
public class ComboBoxWithButton : ComboBox
{
private static int DROPDOWNBUTTON_WIDTH = 17;

private static int BUTTON_WIDTH = 17;

private Button customButton;

Button CustomButton
{
    get
    {
        if (customButton == null)
        {
            customButton = new Button()
            {
                Text = ButtonText,
                FlatStyle = ButtonFlatStyle,
                Parent = this,
                TextAlign = ButtonTextAlign,
                TextImageRelation = ButtonTextImageRelation
            };
            customButton.FlatAppearance.BorderSize = 0;
        }
        customButton.SizeChanged += CustomButton_SizeChanged;
        return customButton;
    }
}

private void CustomButton_SizeChanged(object sender, EventArgs e)
{
    BUTTON_WIDTH = customButton.Width;
}

[Browsable(true), Description("Occurs when the component is clicked."), Category("Button")]
[DisplayName("Click")]
public event EventHandler<EventArgs> ButtonClicked;

[Browsable(true), Description("The button text associated with the control"), Category("Button")]
[DisplayName("Text")]
[DefaultValue("?")]
public string ButtonText
{
    get
    {
        if (customButton == null)
        {
            return GetDefaultValue<string>(this, "ButtonText");
        }
        else
        {
            return customButton.Text;
        }
    }
    set { customButton.Text = value; }
}
[Browsable(true), Description("Determines the appearance of the control when a user moves the mouse over the control and clicks."), Category("Button")]
[DisplayName("FlatStyle")]
[DefaultValue(FlatStyle.Flat)]
public FlatStyle ButtonFlatStyle
{
    get
    {
        if (customButton == null)
        {
            return GetDefaultValue<FlatStyle>(this, "ButtonFlatStyle");
        }
        else
        {
            return customButton.FlatStyle;
        }
    }
    set { customButton.FlatStyle = value; }
}
[Browsable(true), Description("The alignment of the text that will be displayed on the control."), Category("Button")]
[DisplayName("TextAlign")]
[DefaultValue(System.Drawing.ContentAlignment.MiddleCenter)]
public System.Drawing.ContentAlignment ButtonTextAlign
{
    get
    {
        if (customButton == null)
        {
            return GetDefaultValue<System.Drawing.ContentAlignment>(this, "ButtonTextAlign");
        }
        else
        {
            return customButton.TextAlign;
        }
    }
    set { customButton.TextAlign = value; }
}
[Browsable(true), Description("Specifies the relative location of the image to the text on the button."), Category("Button")]
[DisplayName("TextImageRelation")]
[DefaultValue(TextImageRelation.Overlay)]
public TextImageRelation ButtonTextImageRelation
{
    get
    {
        if (customButton == null)
        {
            return GetDefaultValue<TextImageRelation>(this, "ButtonTextImageRelation");
        }
        else
        {
            return customButton.TextImageRelation;
        }
    }
    set { customButton.TextImageRelation = value; }
}
[Browsable(true), Description("The button image associated with the control"), Category("Button")]
[DisplayName("Image")]
public Image ButtonImage
{
    get
    {
        if (customButton == null)
        {
            return GetDefaultValue<Image>(this, "ButtonImage");
        }
        else
        {
            return customButton.Image;
        }
    }
    set { customButton.Image = value; }
}

[Browsable(true), Description("Indicates if the button associated with the control is always visable"), Category("Button")]
[DisplayName("ButtonAlwaysVisible")]
[DefaultValue(false)]
public bool ButtonAlwaysVisible { get; set; }

static T GetDefaultValue<T>(object obj, string propertyName)
{
    if (obj == null) return default(T);
    var prop = obj.GetType().GetProperty(propertyName);
    if (prop == null) return default(T);
    var attr = prop.GetCustomAttributes(typeof(DefaultValueAttribute), true);
    if (attr.Length != 1) return default(T);
    return (T)((DefaultValueAttribute)attr[0]).Value;
}
public ComboBoxWithButton()
{            
    
    CustomButton.Click += CustomButton_Click;
}

[DefaultValue(8)]
protected internal int EditControlOffset { get; set; } = 4;

protected override void OnHandleCreated(EventArgs e)
{
    base.OnHandleCreated(e);
    UpdateControlsPosition();
}

protected override void WndProc(ref Message m)
{
    base.WndProc(ref m);
    switch (m.Msg)
    {
        case NativeMethods.WM_WINDOWPOSCHANGED:
            UpdateControlsPosition();
            break;
        case NativeMethods.WM_DESTROY:
            if (customButton != null)
            {
                customButton.Click -= CustomButton_Click;
                customButton.Dispose();
            }
            break;
    }
    
}

private void UpdateControlsPosition()
{           
    if (customButton != null)
    {
        SuspendLayout();
        Rectangle arrowRect = NativeMethods.GetComboBoxInfoInternal(Handle, out Rectangle editRect, out IntPtr editHwnd);
        if (arrowRect.IsEmpty || editRect.IsEmpty) return;
        // Same size as the Arrow Button: change as required


        DROPDOWNBUTTON_WIDTH = arrowRect.Width;
        customButton.Size = arrowRect.Size;
        customButton.Location = new Point(arrowRect.Left - customButton.Width - 1, 1);
        editRect.Width = ClientSize.Width - customButton.Width * 2 - EditControlOffset;
        NativeMethods.SetWindowPos(editHwnd, IntPtr.Zero, 0, 0, editRect.Width, editRect.Height, NativeMethods.SWP_Flags);

        ResumeLayout(false);
    }
}

private void CustomButton_Click(object sender, EventArgs e) => OnEditButtonClicked(e);

protected virtual void OnEditButtonClicked(EventArgs e)
{
    ButtonClicked?.Invoke(this, e);
}

internal static Rectangle GetComboArrowBounds(Rectangle bounds)
{            
    return new Rectangle(bounds.Right - DROPDOWNBUTTON_WIDTH, bounds.Top, DROPDOWNBUTTON_WIDTH, bounds.Height);
}
internal static Rectangle GetComboButtonBounds(Rectangle bounds)
{
    return new Rectangle(bounds.Right - BUTTON_WIDTH - BUTTON_WIDTH, bounds.Top, BUTTON_WIDTH, bounds.Height);
}


}

`

Here is the datagridviewcolumn code I have created so far.

`

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>public class DataGridViewComboBoxWithButtonColumn : DataGridViewComboBoxColumn
{
private Button customButton;
public Button CustomButton
{
get
{
if (customButton == null)
{
customButton = new Button()
{
Text = ButtonText,
FlatStyle = ButtonFlatStyle,
TextAlign = ButtonTextAlign,
TextImageRelation = ButtonTextImageRelation
};
customButton.FlatAppearance.BorderSize = 0;
}
return customButton;
}
internal set { customButton = value; }
}
[Browsable(true), Description("Occurs when the component is clicked."), Category("Button")]
[DisplayName("Click")]
public event EventHandler<EventArgs> ButtonClicked;
[Browsable(true), Description("The button text associated with the control"), Category("Button")]
[DisplayName("Text")]
[DefaultValue("?")]
public string ButtonText
{
get
{
if (customButton == null)
{
return GetDefaultValue<string>(this, "ButtonText");
}
else
{
return customButton.Text;
}
}
set { customButton.Text = value; }
}
[Browsable(true), Description("Determines the appearance of the control when a user moves the mouse over the control and clicks."), Category("Button")]
[DisplayName("FlatStyle")]
[DefaultValue(FlatStyle.Flat)]
public FlatStyle ButtonFlatStyle
{
get
{
if (customButton == null)
{
return GetDefaultValue<FlatStyle>(this, "ButtonFlatStyle");
}
else
{
return customButton.FlatStyle;
}
}
set { customButton.FlatStyle = value; }
}
[Browsable(true), Description("The alignment of the text that will be displayed on the control."), Category("Button")]
[DisplayName("TextAlign")]
[DefaultValue(System.Drawing.ContentAlignment.MiddleCenter)]
public System.Drawing.ContentAlignment ButtonTextAlign
{
get
{
if (customButton == null)
{
return GetDefaultValue<System.Drawing.ContentAlignment>(this, "ButtonTextAlign");
}
else
{
return customButton.TextAlign;
}
}
set { customButton.TextAlign = value; }
}
[Browsable(true), Description("Specifies the relative location of the image to the text on the button."), Category("Button")]
[DisplayName("TextImageRelation")]
[DefaultValue(TextImageRelation.Overlay)]
public TextImageRelation ButtonTextImageRelation
{
get
{
if (customButton == null)
{
return GetDefaultValue<TextImageRelation>(this, "ButtonTextImageRelation");
}
else
{
return customButton.TextImageRelation;
}
}
set { customButton.TextImageRelation = value; }
}
[Browsable(true), Description("The button image associated with the control"), Category("Button")]
[DisplayName("Image")]
public Image ButtonImage
{
get
{
if (customButton == null)
{
return GetDefaultValue<Image>(this, "ButtonImage");
}
else
{
return customButton.Image;
}
}
set { customButton.Image = value; }
}
[Browsable(true), Description("Indicates if the button associated with the control is always visable"), Category("Button")]
[DisplayName("ButtonAlwaysVisible")]
[DefaultValue(false)]
public bool ButtonAlwaysVisible { get; set; }
public DataGridViewComboBoxWithButtonColumn() : base()
{
DataGridViewComboBoxWithButtonCell template = new DataGridViewComboBoxWithButtonCell();
template.CustomButton = CustomButton;
template.ButtonClicked += ButtonClicked;
this.CellTemplate = template;
}
public override DataGridViewCell CellTemplate
{
get
{
return base.CellTemplate;
}
set
{
if (value != null && !(value.GetType().IsAssignableFrom(typeof(DataGridViewComboBoxWithButtonCell))))
{
throw new InvalidCastException("Must be a DataGridViewComboBoxWithButtonCell");
}
base.CellTemplate = value;
}
}
public override object Clone()
{
var clone = (DataGridViewComboBoxWithButtonColumn)base.Clone();
clone.CustomButton = CustomButton;
clone.ButtonAlwaysVisible = ButtonAlwaysVisible;
return clone;
}
static T GetDefaultValue<T>(object obj, string propertyName)
{
if (obj == null) return default(T);
var prop = obj.GetType().GetProperty(propertyName);
if (prop == null) return default(T);
var attr = prop.GetCustomAttributes(typeof(DefaultValueAttribute), true);
if (attr.Length != 1) return default(T);
return (T)((DefaultValueAttribute)attr[0]).Value;
}
}
</code>
<code>public class DataGridViewComboBoxWithButtonColumn : DataGridViewComboBoxColumn { private Button customButton; public Button CustomButton { get { if (customButton == null) { customButton = new Button() { Text = ButtonText, FlatStyle = ButtonFlatStyle, TextAlign = ButtonTextAlign, TextImageRelation = ButtonTextImageRelation }; customButton.FlatAppearance.BorderSize = 0; } return customButton; } internal set { customButton = value; } } [Browsable(true), Description("Occurs when the component is clicked."), Category("Button")] [DisplayName("Click")] public event EventHandler<EventArgs> ButtonClicked; [Browsable(true), Description("The button text associated with the control"), Category("Button")] [DisplayName("Text")] [DefaultValue("?")] public string ButtonText { get { if (customButton == null) { return GetDefaultValue<string>(this, "ButtonText"); } else { return customButton.Text; } } set { customButton.Text = value; } } [Browsable(true), Description("Determines the appearance of the control when a user moves the mouse over the control and clicks."), Category("Button")] [DisplayName("FlatStyle")] [DefaultValue(FlatStyle.Flat)] public FlatStyle ButtonFlatStyle { get { if (customButton == null) { return GetDefaultValue<FlatStyle>(this, "ButtonFlatStyle"); } else { return customButton.FlatStyle; } } set { customButton.FlatStyle = value; } } [Browsable(true), Description("The alignment of the text that will be displayed on the control."), Category("Button")] [DisplayName("TextAlign")] [DefaultValue(System.Drawing.ContentAlignment.MiddleCenter)] public System.Drawing.ContentAlignment ButtonTextAlign { get { if (customButton == null) { return GetDefaultValue<System.Drawing.ContentAlignment>(this, "ButtonTextAlign"); } else { return customButton.TextAlign; } } set { customButton.TextAlign = value; } } [Browsable(true), Description("Specifies the relative location of the image to the text on the button."), Category("Button")] [DisplayName("TextImageRelation")] [DefaultValue(TextImageRelation.Overlay)] public TextImageRelation ButtonTextImageRelation { get { if (customButton == null) { return GetDefaultValue<TextImageRelation>(this, "ButtonTextImageRelation"); } else { return customButton.TextImageRelation; } } set { customButton.TextImageRelation = value; } } [Browsable(true), Description("The button image associated with the control"), Category("Button")] [DisplayName("Image")] public Image ButtonImage { get { if (customButton == null) { return GetDefaultValue<Image>(this, "ButtonImage"); } else { return customButton.Image; } } set { customButton.Image = value; } } [Browsable(true), Description("Indicates if the button associated with the control is always visable"), Category("Button")] [DisplayName("ButtonAlwaysVisible")] [DefaultValue(false)] public bool ButtonAlwaysVisible { get; set; } public DataGridViewComboBoxWithButtonColumn() : base() { DataGridViewComboBoxWithButtonCell template = new DataGridViewComboBoxWithButtonCell(); template.CustomButton = CustomButton; template.ButtonClicked += ButtonClicked; this.CellTemplate = template; } public override DataGridViewCell CellTemplate { get { return base.CellTemplate; } set { if (value != null && !(value.GetType().IsAssignableFrom(typeof(DataGridViewComboBoxWithButtonCell)))) { throw new InvalidCastException("Must be a DataGridViewComboBoxWithButtonCell"); } base.CellTemplate = value; } } public override object Clone() { var clone = (DataGridViewComboBoxWithButtonColumn)base.Clone(); clone.CustomButton = CustomButton; clone.ButtonAlwaysVisible = ButtonAlwaysVisible; return clone; } static T GetDefaultValue<T>(object obj, string propertyName) { if (obj == null) return default(T); var prop = obj.GetType().GetProperty(propertyName); if (prop == null) return default(T); var attr = prop.GetCustomAttributes(typeof(DefaultValueAttribute), true); if (attr.Length != 1) return default(T); return (T)((DefaultValueAttribute)attr[0]).Value; } } </code>
public class DataGridViewComboBoxWithButtonColumn : DataGridViewComboBoxColumn
{

private Button customButton;
public Button CustomButton
{
    get
    {
        if (customButton == null)
        {
            customButton = new Button()
            {
                Text = ButtonText,
                FlatStyle = ButtonFlatStyle,
                TextAlign = ButtonTextAlign,
                TextImageRelation = ButtonTextImageRelation
            };
            customButton.FlatAppearance.BorderSize = 0;
        }
        
        return customButton;
    }
    internal set { customButton = value; }
        
}



[Browsable(true), Description("Occurs when the component is clicked."), Category("Button")]
[DisplayName("Click")]
public event EventHandler<EventArgs> ButtonClicked;

[Browsable(true), Description("The button text associated with the control"), Category("Button")]
[DisplayName("Text")]
[DefaultValue("?")]
public string ButtonText
{
    get
    {
        if (customButton == null)
        {
            return GetDefaultValue<string>(this, "ButtonText");
        }
        else
        {
            return customButton.Text;
        }
    }
    set { customButton.Text = value; }
}
[Browsable(true), Description("Determines the appearance of the control when a user moves the mouse over the control and clicks."), Category("Button")]
[DisplayName("FlatStyle")]
[DefaultValue(FlatStyle.Flat)]
public FlatStyle ButtonFlatStyle
{
    get
    {
        if (customButton == null)
        {
            return GetDefaultValue<FlatStyle>(this, "ButtonFlatStyle");
        }
        else
        {
            return customButton.FlatStyle;
        }
    }
    set { customButton.FlatStyle = value; }
}
[Browsable(true), Description("The alignment of the text that will be displayed on the control."), Category("Button")]
[DisplayName("TextAlign")]
[DefaultValue(System.Drawing.ContentAlignment.MiddleCenter)]
public System.Drawing.ContentAlignment ButtonTextAlign
{
    get
    {
        if (customButton == null)
        {
            return GetDefaultValue<System.Drawing.ContentAlignment>(this, "ButtonTextAlign");
        }
        else
        {
            return customButton.TextAlign;
        }
    }
    set { customButton.TextAlign = value; }
}
[Browsable(true), Description("Specifies the relative location of the image to the text on the button."), Category("Button")]
[DisplayName("TextImageRelation")]
[DefaultValue(TextImageRelation.Overlay)]
public TextImageRelation ButtonTextImageRelation
{
    get
    {
        if (customButton == null)
        {
            return GetDefaultValue<TextImageRelation>(this, "ButtonTextImageRelation");
        }
        else
        {
            return customButton.TextImageRelation;
        }
    }
    set { customButton.TextImageRelation = value; }
}
[Browsable(true), Description("The button image associated with the control"), Category("Button")]
[DisplayName("Image")]
public Image ButtonImage
{
    get
    {
        if (customButton == null)
        {
            return GetDefaultValue<Image>(this, "ButtonImage");
        }
        else
        {
            return customButton.Image;
        }
    }
    set { customButton.Image = value; }
}

[Browsable(true), Description("Indicates if the button associated with the control is always visable"), Category("Button")]
[DisplayName("ButtonAlwaysVisible")]
[DefaultValue(false)]
public bool ButtonAlwaysVisible { get; set; }
public DataGridViewComboBoxWithButtonColumn() : base()
{            
    DataGridViewComboBoxWithButtonCell template = new DataGridViewComboBoxWithButtonCell();
    template.CustomButton = CustomButton;
    template.ButtonClicked += ButtonClicked; 
    this.CellTemplate = template;
}

public override DataGridViewCell CellTemplate
{
    get
    {
        return base.CellTemplate;
    }
    set
    {
        if (value != null && !(value.GetType().IsAssignableFrom(typeof(DataGridViewComboBoxWithButtonCell))))
        {
            throw new InvalidCastException("Must be a DataGridViewComboBoxWithButtonCell");
        }

        base.CellTemplate = value;
    }
}
public override object Clone()
{
    var clone = (DataGridViewComboBoxWithButtonColumn)base.Clone();
    clone.CustomButton = CustomButton;
    clone.ButtonAlwaysVisible = ButtonAlwaysVisible;
    return clone;
}
static T GetDefaultValue<T>(object obj, string propertyName)
{
    if (obj == null) return default(T);
    var prop = obj.GetType().GetProperty(propertyName);
    if (prop == null) return default(T);
    var attr = prop.GetCustomAttributes(typeof(DefaultValueAttribute), true);
    if (attr.Length != 1) return default(T);
    return (T)((DefaultValueAttribute)attr[0]).Value;
}
}

`

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>public class DataGridViewComboBoxWithButtonCell : DataGridViewComboBoxCell
{
private static int DROPDOWNBUTTON_WIDTH = 17;
private static int BUTTON_WIDTH = 17;
private Button customButton;
public Button CustomButton
{
get
{
if (customButton == null)
{
customButton = new Button();
}
return customButton;
}
internal set
{
customButton = value;
customButton.SizeChanged += CustomButton_SizeChanged;
customButton.MouseDown += CustomButton_MouseDown;
customButton.MouseEnter += CustomButton_MouseEnter;
customButton.MouseLeave += CustomButton_MouseLeave;
customButton.MouseHover += CustomButton_MouseHover;
}
}
[Browsable(true), Description("Occurs when the component is clicked."), Category("Button")]
[DisplayName("Click")]
public event EventHandler<EventArgs> ButtonClicked;
private void CustomButton_SizeChanged(object sender, EventArgs e)
{
BUTTON_WIDTH = customButton.Width;
}
public DataGridViewComboBoxWithButtonCell() : base()
{
}
private void CustomButton_MouseHover(object sender, EventArgs e)
{
CustomButtonState = PushButtonState.Hot;
}
private void CustomButton_MouseLeave(object sender, EventArgs e)
{
CustomButtonState = PushButtonState.Normal;
}
private void CustomButton_MouseEnter(object sender, EventArgs e)
{
CustomButtonState = PushButtonState.Hot;
}
private void CustomButton_MouseDown(object sender, MouseEventArgs e)
{
CustomButtonState = PushButtonState.Pressed;
}
protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
{
base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
BeforePaintContent(graphics, cellBounds, cellState, cellStyle, paintParts);
if (paintParts.HasFlag(DataGridViewPaintParts.ContentForeground))
{
Rectangle contentBounds = cellBounds;
contentBounds.Width -= DROPDOWNBUTTON_WIDTH;
TextFormatFlags flags = TextFormatFlags.NoPrefix | TextFormatFlags.EndEllipsis | TextFormatFlags.VerticalCenter | TextFormatFlags.LeftAndRightPadding | TextFormatFlags.PreserveGraphicsClipping;
TextRenderer.DrawText(graphics, Convert.ToString(formattedValue), cellStyle.Font, contentBounds, cellStyle.ForeColor, flags);
}
AfterPaintContent(graphics, clipBounds, cellBounds, rowIndex, cellStyle, advancedBorderStyle, paintParts);
}
protected void BeforePaintContent(Graphics graphics, Rectangle cellBounds, DataGridViewElementStates cellState, DataGridViewCellStyle cellStyle, DataGridViewPaintParts paintParts)
{
if (paintParts.HasFlag(DataGridViewPaintParts.Background))
{
using (Brush brush = new SolidBrush(cellStyle.BackColor))
{
graphics.FillRectangle(brush, cellBounds);
}
}
if (paintParts.HasFlag(DataGridViewPaintParts.SelectionBackground) && cellState.HasFlag(DataGridViewElementStates.Selected))
{
using (Brush brush = new SolidBrush(cellStyle.SelectionBackColor))
{
graphics.FillRectangle(brush, cellBounds);
}
}
if (paintParts.HasFlag(DataGridViewPaintParts.ContentBackground))
{
ButtonState legacyState = ButtonState.Normal;
if ((DataGridView.Site == null) || !DataGridView.Site.DesignMode)
{
if (cellState.HasFlag(DataGridViewElementStates.ReadOnly))
{
state = ComboBoxState.Disabled;
legacyState = ButtonState.Inactive;
}
else if (cellBounds.Contains(DataGridView.PointToClient(DataGridView.MousePosition)))
{
if (DataGridView.MouseButtons.HasFlag(MouseButtons.Left))
{
state = ComboBoxState.Pressed;
legacyState = ButtonState.Pushed;
}
else
{
state = ComboBoxState.Hot;
}
}
}
Rectangle comboBounds = cellBounds;
comboBounds.Width--;
DrawComboBox(graphics, comboBounds);
}
}
protected void AfterPaintContent(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
{
if (paintParts.HasFlag(DataGridViewPaintParts.ErrorIcon))
{
base.PaintErrorIcon(graphics, clipBounds, cellBounds, GetErrorText(rowIndex));
}
if (paintParts.HasFlag(DataGridViewPaintParts.Border))
{
base.PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle);
}
if (paintParts.HasFlag(DataGridViewPaintParts.Focus) && (DataGridView.CurrentCell == this))
{
Rectangle focusBounds = cellBounds;
focusBounds.Width--;
focusBounds.Height--;
ControlPaint.DrawFocusRectangle(graphics, focusBounds);
}
}
internal static Rectangle GetComboArrowBounds(Rectangle bounds)
{
return new Rectangle(bounds.Right - DROPDOWNBUTTON_WIDTH, bounds.Top, DROPDOWNBUTTON_WIDTH, bounds.Height);
}
internal static Rectangle GetComboButtonBounds(Rectangle bounds)
{
return new Rectangle(bounds.Right - BUTTON_WIDTH - BUTTON_WIDTH, bounds.Top, BUTTON_WIDTH, bounds.Height);
}
internal static PushButtonState CustomButtonState
{
get; private set;
} = PushButtonState.Normal;
internal ComboBoxState state = ComboBoxState.Normal;
private void DrawComboBox(Graphics graphics, Rectangle bounds)
{
Rectangle comboBounds = bounds;
Rectangle ButtonBounds = GetComboButtonBounds(comboBounds);
Rectangle ArrowBounds = GetComboArrowBounds(comboBounds);
comboBounds.Inflate(1, 1);
if (ButtonBounds.X >= (bounds.Width + bounds.X))
{
ButtonBounds.X = (bounds.Width + bounds.X) - (ButtonBounds.Width + ArrowBounds.Width);
}
ButtonRenderer.DrawButton(graphics, ButtonBounds, CustomButton.Text, CustomButton.Font, TextFormatFlags.Default, CustomButton.CanFocus, CustomButtonState);
if (ArrowBounds.X >= (bounds.Width + bounds.X))
{
ArrowBounds.X = (bounds.Width + bounds.X) - ArrowBounds.Width;
}
Rectangle buttonClip = ArrowBounds;
buttonClip.Inflate(-2, -2);
using (Region oldClip = graphics.Clip.Clone())
{
graphics.SetClip(buttonClip, System.Drawing.Drawing2D.CombineMode.Intersect);
ComboBoxRenderer.DrawDropDownButton(graphics, ArrowBounds, state);
graphics.SetClip(oldClip, System.Drawing.Drawing2D.CombineMode.Replace);
}
}
public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
{
base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
ComboBoxWithButton comboBox = base.DataGridView.EditingControl as ComboBoxWithButton;
if (comboBox != null)
{
comboBox.BeginUpdate();
comboBox.DropDownStyle = ComboBoxStyle.DropDown;
comboBox.AutoCompleteSource = AutoCompleteSource.ListItems;
comboBox.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
comboBox.EndUpdate();
}
}
public override Type EditType
{
get
{
return typeof(ComboBoxWithButtonEditingControl);
}
}
public override Type ValueType
{
get
{
return base.ValueType;
}
}
public override object Clone()
{
var clone = (DataGridViewComboBoxWithButtonCell)base.Clone();
return clone;
}
}
</code>
<code>public class DataGridViewComboBoxWithButtonCell : DataGridViewComboBoxCell { private static int DROPDOWNBUTTON_WIDTH = 17; private static int BUTTON_WIDTH = 17; private Button customButton; public Button CustomButton { get { if (customButton == null) { customButton = new Button(); } return customButton; } internal set { customButton = value; customButton.SizeChanged += CustomButton_SizeChanged; customButton.MouseDown += CustomButton_MouseDown; customButton.MouseEnter += CustomButton_MouseEnter; customButton.MouseLeave += CustomButton_MouseLeave; customButton.MouseHover += CustomButton_MouseHover; } } [Browsable(true), Description("Occurs when the component is clicked."), Category("Button")] [DisplayName("Click")] public event EventHandler<EventArgs> ButtonClicked; private void CustomButton_SizeChanged(object sender, EventArgs e) { BUTTON_WIDTH = customButton.Width; } public DataGridViewComboBoxWithButtonCell() : base() { } private void CustomButton_MouseHover(object sender, EventArgs e) { CustomButtonState = PushButtonState.Hot; } private void CustomButton_MouseLeave(object sender, EventArgs e) { CustomButtonState = PushButtonState.Normal; } private void CustomButton_MouseEnter(object sender, EventArgs e) { CustomButtonState = PushButtonState.Hot; } private void CustomButton_MouseDown(object sender, MouseEventArgs e) { CustomButtonState = PushButtonState.Pressed; } protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts) { base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts); BeforePaintContent(graphics, cellBounds, cellState, cellStyle, paintParts); if (paintParts.HasFlag(DataGridViewPaintParts.ContentForeground)) { Rectangle contentBounds = cellBounds; contentBounds.Width -= DROPDOWNBUTTON_WIDTH; TextFormatFlags flags = TextFormatFlags.NoPrefix | TextFormatFlags.EndEllipsis | TextFormatFlags.VerticalCenter | TextFormatFlags.LeftAndRightPadding | TextFormatFlags.PreserveGraphicsClipping; TextRenderer.DrawText(graphics, Convert.ToString(formattedValue), cellStyle.Font, contentBounds, cellStyle.ForeColor, flags); } AfterPaintContent(graphics, clipBounds, cellBounds, rowIndex, cellStyle, advancedBorderStyle, paintParts); } protected void BeforePaintContent(Graphics graphics, Rectangle cellBounds, DataGridViewElementStates cellState, DataGridViewCellStyle cellStyle, DataGridViewPaintParts paintParts) { if (paintParts.HasFlag(DataGridViewPaintParts.Background)) { using (Brush brush = new SolidBrush(cellStyle.BackColor)) { graphics.FillRectangle(brush, cellBounds); } } if (paintParts.HasFlag(DataGridViewPaintParts.SelectionBackground) && cellState.HasFlag(DataGridViewElementStates.Selected)) { using (Brush brush = new SolidBrush(cellStyle.SelectionBackColor)) { graphics.FillRectangle(brush, cellBounds); } } if (paintParts.HasFlag(DataGridViewPaintParts.ContentBackground)) { ButtonState legacyState = ButtonState.Normal; if ((DataGridView.Site == null) || !DataGridView.Site.DesignMode) { if (cellState.HasFlag(DataGridViewElementStates.ReadOnly)) { state = ComboBoxState.Disabled; legacyState = ButtonState.Inactive; } else if (cellBounds.Contains(DataGridView.PointToClient(DataGridView.MousePosition))) { if (DataGridView.MouseButtons.HasFlag(MouseButtons.Left)) { state = ComboBoxState.Pressed; legacyState = ButtonState.Pushed; } else { state = ComboBoxState.Hot; } } } Rectangle comboBounds = cellBounds; comboBounds.Width--; DrawComboBox(graphics, comboBounds); } } protected void AfterPaintContent(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts) { if (paintParts.HasFlag(DataGridViewPaintParts.ErrorIcon)) { base.PaintErrorIcon(graphics, clipBounds, cellBounds, GetErrorText(rowIndex)); } if (paintParts.HasFlag(DataGridViewPaintParts.Border)) { base.PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle); } if (paintParts.HasFlag(DataGridViewPaintParts.Focus) && (DataGridView.CurrentCell == this)) { Rectangle focusBounds = cellBounds; focusBounds.Width--; focusBounds.Height--; ControlPaint.DrawFocusRectangle(graphics, focusBounds); } } internal static Rectangle GetComboArrowBounds(Rectangle bounds) { return new Rectangle(bounds.Right - DROPDOWNBUTTON_WIDTH, bounds.Top, DROPDOWNBUTTON_WIDTH, bounds.Height); } internal static Rectangle GetComboButtonBounds(Rectangle bounds) { return new Rectangle(bounds.Right - BUTTON_WIDTH - BUTTON_WIDTH, bounds.Top, BUTTON_WIDTH, bounds.Height); } internal static PushButtonState CustomButtonState { get; private set; } = PushButtonState.Normal; internal ComboBoxState state = ComboBoxState.Normal; private void DrawComboBox(Graphics graphics, Rectangle bounds) { Rectangle comboBounds = bounds; Rectangle ButtonBounds = GetComboButtonBounds(comboBounds); Rectangle ArrowBounds = GetComboArrowBounds(comboBounds); comboBounds.Inflate(1, 1); if (ButtonBounds.X >= (bounds.Width + bounds.X)) { ButtonBounds.X = (bounds.Width + bounds.X) - (ButtonBounds.Width + ArrowBounds.Width); } ButtonRenderer.DrawButton(graphics, ButtonBounds, CustomButton.Text, CustomButton.Font, TextFormatFlags.Default, CustomButton.CanFocus, CustomButtonState); if (ArrowBounds.X >= (bounds.Width + bounds.X)) { ArrowBounds.X = (bounds.Width + bounds.X) - ArrowBounds.Width; } Rectangle buttonClip = ArrowBounds; buttonClip.Inflate(-2, -2); using (Region oldClip = graphics.Clip.Clone()) { graphics.SetClip(buttonClip, System.Drawing.Drawing2D.CombineMode.Intersect); ComboBoxRenderer.DrawDropDownButton(graphics, ArrowBounds, state); graphics.SetClip(oldClip, System.Drawing.Drawing2D.CombineMode.Replace); } } public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle) { base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle); ComboBoxWithButton comboBox = base.DataGridView.EditingControl as ComboBoxWithButton; if (comboBox != null) { comboBox.BeginUpdate(); comboBox.DropDownStyle = ComboBoxStyle.DropDown; comboBox.AutoCompleteSource = AutoCompleteSource.ListItems; comboBox.AutoCompleteMode = AutoCompleteMode.SuggestAppend; comboBox.EndUpdate(); } } public override Type EditType { get { return typeof(ComboBoxWithButtonEditingControl); } } public override Type ValueType { get { return base.ValueType; } } public override object Clone() { var clone = (DataGridViewComboBoxWithButtonCell)base.Clone(); return clone; } } </code>
public class DataGridViewComboBoxWithButtonCell : DataGridViewComboBoxCell
{
private static int DROPDOWNBUTTON_WIDTH = 17;
private static int BUTTON_WIDTH = 17;
private Button customButton;
public Button CustomButton
{
    get
    {
        
        if (customButton == null)
        {
            customButton = new Button();
        }
        return customButton;
    }
    internal set 
    { 
        customButton = value;
        customButton.SizeChanged += CustomButton_SizeChanged;
        customButton.MouseDown += CustomButton_MouseDown;
        customButton.MouseEnter += CustomButton_MouseEnter;
        customButton.MouseLeave += CustomButton_MouseLeave;
        customButton.MouseHover += CustomButton_MouseHover;
    }

}
[Browsable(true), Description("Occurs when the component is clicked."), Category("Button")]
[DisplayName("Click")]
public event EventHandler<EventArgs> ButtonClicked;
private void CustomButton_SizeChanged(object sender, EventArgs e)
{
    BUTTON_WIDTH = customButton.Width;
}
public DataGridViewComboBoxWithButtonCell() : base()
{
}
private void CustomButton_MouseHover(object sender, EventArgs e)
{
    CustomButtonState = PushButtonState.Hot;
}

private void CustomButton_MouseLeave(object sender, EventArgs e)
{
    CustomButtonState = PushButtonState.Normal;
}

private void CustomButton_MouseEnter(object sender, EventArgs e)
{
    CustomButtonState = PushButtonState.Hot;
}

private void CustomButton_MouseDown(object sender, MouseEventArgs e)
{
    CustomButtonState = PushButtonState.Pressed;
}
protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
{
    base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);



    BeforePaintContent(graphics, cellBounds, cellState, cellStyle, paintParts);

    if (paintParts.HasFlag(DataGridViewPaintParts.ContentForeground))
    {
        Rectangle contentBounds = cellBounds;
        contentBounds.Width -= DROPDOWNBUTTON_WIDTH;
        TextFormatFlags flags = TextFormatFlags.NoPrefix | TextFormatFlags.EndEllipsis | TextFormatFlags.VerticalCenter | TextFormatFlags.LeftAndRightPadding | TextFormatFlags.PreserveGraphicsClipping;
        TextRenderer.DrawText(graphics, Convert.ToString(formattedValue), cellStyle.Font, contentBounds, cellStyle.ForeColor, flags);
    }

    AfterPaintContent(graphics, clipBounds, cellBounds, rowIndex, cellStyle, advancedBorderStyle, paintParts);

}
protected void BeforePaintContent(Graphics graphics, Rectangle cellBounds, DataGridViewElementStates cellState, DataGridViewCellStyle cellStyle, DataGridViewPaintParts paintParts)
{
    if (paintParts.HasFlag(DataGridViewPaintParts.Background))
    {
        using (Brush brush = new SolidBrush(cellStyle.BackColor))
        {
            graphics.FillRectangle(brush, cellBounds);
        }
    }

    if (paintParts.HasFlag(DataGridViewPaintParts.SelectionBackground) && cellState.HasFlag(DataGridViewElementStates.Selected))
    {
        using (Brush brush = new SolidBrush(cellStyle.SelectionBackColor))
        {
            graphics.FillRectangle(brush, cellBounds);
        }
    }

    if (paintParts.HasFlag(DataGridViewPaintParts.ContentBackground))
    {
        
        ButtonState legacyState = ButtonState.Normal;

        if ((DataGridView.Site == null) || !DataGridView.Site.DesignMode)
        {
            if (cellState.HasFlag(DataGridViewElementStates.ReadOnly))
            {
                state = ComboBoxState.Disabled;
                legacyState = ButtonState.Inactive;
            }
            else if (cellBounds.Contains(DataGridView.PointToClient(DataGridView.MousePosition)))
            {
                if (DataGridView.MouseButtons.HasFlag(MouseButtons.Left))
                {
                    state = ComboBoxState.Pressed;
                    legacyState = ButtonState.Pushed;
                }
                else
                {
                    state = ComboBoxState.Hot;
                }
            }
        }

        Rectangle comboBounds = cellBounds;
        comboBounds.Width--;

        DrawComboBox(graphics, comboBounds);
    }
}
protected void AfterPaintContent(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
{
    if (paintParts.HasFlag(DataGridViewPaintParts.ErrorIcon))
    {
        base.PaintErrorIcon(graphics, clipBounds, cellBounds, GetErrorText(rowIndex));
    }

    if (paintParts.HasFlag(DataGridViewPaintParts.Border))
    {
        base.PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle);
    }

    if (paintParts.HasFlag(DataGridViewPaintParts.Focus) && (DataGridView.CurrentCell == this))
    {
        Rectangle focusBounds = cellBounds;
        focusBounds.Width--;
        focusBounds.Height--;
        ControlPaint.DrawFocusRectangle(graphics, focusBounds);
    }
}
internal static Rectangle GetComboArrowBounds(Rectangle bounds)
{
    return new Rectangle(bounds.Right - DROPDOWNBUTTON_WIDTH, bounds.Top, DROPDOWNBUTTON_WIDTH, bounds.Height);
}
internal static Rectangle GetComboButtonBounds(Rectangle bounds)
{
    return new Rectangle(bounds.Right - BUTTON_WIDTH - BUTTON_WIDTH, bounds.Top, BUTTON_WIDTH, bounds.Height);
}
internal static PushButtonState CustomButtonState
{
    get; private set;
} = PushButtonState.Normal;
internal ComboBoxState state = ComboBoxState.Normal;
private void DrawComboBox(Graphics graphics, Rectangle bounds)
{
    Rectangle comboBounds = bounds;
    Rectangle ButtonBounds = GetComboButtonBounds(comboBounds);
    Rectangle ArrowBounds = GetComboArrowBounds(comboBounds);

    comboBounds.Inflate(1, 1);
    if (ButtonBounds.X >= (bounds.Width + bounds.X))
    {
        ButtonBounds.X = (bounds.Width + bounds.X) - (ButtonBounds.Width + ArrowBounds.Width);
    }
    ButtonRenderer.DrawButton(graphics, ButtonBounds, CustomButton.Text, CustomButton.Font, TextFormatFlags.Default, CustomButton.CanFocus, CustomButtonState);


    if (ArrowBounds.X >= (bounds.Width + bounds.X))
    {
        ArrowBounds.X = (bounds.Width + bounds.X) - ArrowBounds.Width;
    }
    Rectangle buttonClip = ArrowBounds;
    buttonClip.Inflate(-2, -2);

    using (Region oldClip = graphics.Clip.Clone())
    {
        graphics.SetClip(buttonClip, System.Drawing.Drawing2D.CombineMode.Intersect);
        ComboBoxRenderer.DrawDropDownButton(graphics, ArrowBounds, state);
        graphics.SetClip(oldClip, System.Drawing.Drawing2D.CombineMode.Replace);
    }
}

    public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
    {
    base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
    ComboBoxWithButton comboBox = base.DataGridView.EditingControl as ComboBoxWithButton;

    if (comboBox != null)
    {
        comboBox.BeginUpdate();
        comboBox.DropDownStyle = ComboBoxStyle.DropDown;
        comboBox.AutoCompleteSource = AutoCompleteSource.ListItems;
        comboBox.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
        comboBox.EndUpdate();
    }
}
public override Type EditType
{
    get
    {
        return typeof(ComboBoxWithButtonEditingControl);
    }
}
public override Type ValueType
{
    get
    {
        return base.ValueType;
    }
}

public override object Clone()
{
    var clone = (DataGridViewComboBoxWithButtonCell)base.Clone();
    return clone;
}
}

`

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>internal class ComboBoxWithButtonEditingControl : ComboBoxWithButton, IDataGridViewEditingControl
{
private DataGridView dataGridView;
private bool valueChanged;
private int rowIndex;
public virtual DataGridView EditingControlDataGridView
{
get
{
return dataGridView;
}
set
{
dataGridView = value;
}
}
public virtual object EditingControlFormattedValue
{
get
{
return GetEditingControlFormattedValue(DataGridViewDataErrorContexts.Formatting);
}
set
{
string text = value as string;
if (text != null)
{
Text = text;
if (string.Compare(text, Text, ignoreCase: true, CultureInfo.CurrentCulture) != 0)
{
SelectedIndex = -1;
}
}
}
}
public virtual int EditingControlRowIndex
{
get
{
return rowIndex;
}
set
{
rowIndex = value;
}
}
public virtual bool EditingControlValueChanged
{
get
{
return valueChanged;
}
set
{
valueChanged = value;
}
}
public virtual Cursor EditingPanelCursor => Cursors.Default;
public virtual bool RepositionEditingControlOnValueChange => false;
public ComboBoxWithButtonEditingControl()
{
base.TabStop = false;
}
public virtual void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
{
Font = dataGridViewCellStyle.Font;
if (dataGridViewCellStyle.BackColor.A < byte.MaxValue)
{
Color backColor = (BackColor = Color.FromArgb(255, dataGridViewCellStyle.BackColor));
dataGridView.EditingPanel.BackColor = backColor;
}
else
{
BackColor = dataGridViewCellStyle.BackColor;
}
ForeColor = dataGridViewCellStyle.ForeColor;
}
public virtual bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey)
{
if ((keyData & Keys.KeyCode) == Keys.Down || (keyData & Keys.KeyCode) == Keys.Up || (base.DroppedDown && (keyData & Keys.KeyCode) == Keys.Escape) || (keyData & Keys.KeyCode) == Keys.Return)
{
return true;
}
return !dataGridViewWantsInputKey;
}
public virtual object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
{
return Text;
}
public virtual void PrepareEditingControlForEdit(bool selectAll)
{
if (selectAll)
{
SelectAll();
}
}
private void NotifyDataGridViewOfValueChange()
{
valueChanged = true;
dataGridView.NotifyCurrentCellDirty(dirty: true);
}
protected override void OnSelectedIndexChanged(EventArgs e)
{
base.OnSelectedIndexChanged(e);
if (SelectedIndex != -1)
{
NotifyDataGridViewOfValueChange();
}
}
}`
</code>
<code>internal class ComboBoxWithButtonEditingControl : ComboBoxWithButton, IDataGridViewEditingControl { private DataGridView dataGridView; private bool valueChanged; private int rowIndex; public virtual DataGridView EditingControlDataGridView { get { return dataGridView; } set { dataGridView = value; } } public virtual object EditingControlFormattedValue { get { return GetEditingControlFormattedValue(DataGridViewDataErrorContexts.Formatting); } set { string text = value as string; if (text != null) { Text = text; if (string.Compare(text, Text, ignoreCase: true, CultureInfo.CurrentCulture) != 0) { SelectedIndex = -1; } } } } public virtual int EditingControlRowIndex { get { return rowIndex; } set { rowIndex = value; } } public virtual bool EditingControlValueChanged { get { return valueChanged; } set { valueChanged = value; } } public virtual Cursor EditingPanelCursor => Cursors.Default; public virtual bool RepositionEditingControlOnValueChange => false; public ComboBoxWithButtonEditingControl() { base.TabStop = false; } public virtual void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle) { Font = dataGridViewCellStyle.Font; if (dataGridViewCellStyle.BackColor.A < byte.MaxValue) { Color backColor = (BackColor = Color.FromArgb(255, dataGridViewCellStyle.BackColor)); dataGridView.EditingPanel.BackColor = backColor; } else { BackColor = dataGridViewCellStyle.BackColor; } ForeColor = dataGridViewCellStyle.ForeColor; } public virtual bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey) { if ((keyData & Keys.KeyCode) == Keys.Down || (keyData & Keys.KeyCode) == Keys.Up || (base.DroppedDown && (keyData & Keys.KeyCode) == Keys.Escape) || (keyData & Keys.KeyCode) == Keys.Return) { return true; } return !dataGridViewWantsInputKey; } public virtual object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context) { return Text; } public virtual void PrepareEditingControlForEdit(bool selectAll) { if (selectAll) { SelectAll(); } } private void NotifyDataGridViewOfValueChange() { valueChanged = true; dataGridView.NotifyCurrentCellDirty(dirty: true); } protected override void OnSelectedIndexChanged(EventArgs e) { base.OnSelectedIndexChanged(e); if (SelectedIndex != -1) { NotifyDataGridViewOfValueChange(); } } }` </code>
internal class ComboBoxWithButtonEditingControl : ComboBoxWithButton, IDataGridViewEditingControl
{
private DataGridView dataGridView;

private bool valueChanged;

private int rowIndex;

public virtual DataGridView EditingControlDataGridView
{
    get
    {
        return dataGridView;
    }
    set
    {
        dataGridView = value;
    }
}


public virtual object EditingControlFormattedValue
{
    get
    {
        return GetEditingControlFormattedValue(DataGridViewDataErrorContexts.Formatting);
    }
    set
    {
        string text = value as string;
        if (text != null)
        {
            Text = text;
            if (string.Compare(text, Text, ignoreCase: true, CultureInfo.CurrentCulture) != 0)
            {
                SelectedIndex = -1;
            }
        }
    }
}


public virtual int EditingControlRowIndex
{
    get
    {
        return rowIndex;
    }
    set
    {
        rowIndex = value;
    }
}


public virtual bool EditingControlValueChanged
{
    get
    {
        return valueChanged;
    }
    set
    {
        valueChanged = value;
    }
}


public virtual Cursor EditingPanelCursor => Cursors.Default;


public virtual bool RepositionEditingControlOnValueChange => false;


public ComboBoxWithButtonEditingControl()
{
    base.TabStop = false;
}        

public virtual void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
{
    Font = dataGridViewCellStyle.Font;
    if (dataGridViewCellStyle.BackColor.A < byte.MaxValue)
    {
        Color backColor = (BackColor = Color.FromArgb(255, dataGridViewCellStyle.BackColor));
        dataGridView.EditingPanel.BackColor = backColor;
    }
    else
    {
        BackColor = dataGridViewCellStyle.BackColor;
    }

    ForeColor = dataGridViewCellStyle.ForeColor;
}

public virtual bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey)
{
    if ((keyData & Keys.KeyCode) == Keys.Down || (keyData & Keys.KeyCode) == Keys.Up || (base.DroppedDown && (keyData & Keys.KeyCode) == Keys.Escape) || (keyData & Keys.KeyCode) == Keys.Return)
    {
        return true;
    }

    return !dataGridViewWantsInputKey;
}

public virtual object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
{
    return Text;
}

public virtual void PrepareEditingControlForEdit(bool selectAll)
{
    if (selectAll)
    {
        SelectAll();
    }
}

private void NotifyDataGridViewOfValueChange()
{
    valueChanged = true;
    dataGridView.NotifyCurrentCellDirty(dirty: true);
}

protected override void OnSelectedIndexChanged(EventArgs e)
{
    base.OnSelectedIndexChanged(e);
    if (SelectedIndex != -1)
    {
        NotifyDataGridViewOfValueChange();
    }
}
}`

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật