简体   繁体   中英

C# show my custom control on DataGridView even if not editing

I am using the following classes to create a custom column with a numeric up down control. This is working excellent but I would like to show the numeric up down control all the time (even if not editing). The following code put the string value on the control and after clicking the cell it will show the numeric control for editing. I think that I need to override the Paint method but I don't know how to implement it

using System;
using System.Drawing;
using System.Windows.Forms;

namespace Utilities.General.Classes
{
    public class NumericUpDownColumn : DataGridViewColumn
    {
        public NumericUpDownColumn() : base(new NumericUpDownCell())
        { }
        public override DataGridViewCell CellTemplate
        {
            get { return base.CellTemplate; }
            set
            {
                //Ensure that the cell used for the template is a NumericUpDown
                if(value?.GetType().IsAssignableFrom(typeof(NumericUpDownCell)) == false)
                {
                    throw new InvalidCastException("Must be a string");
                }
                base.CellTemplate = value;
            }
        }
    }

    public class NumericUpDownCell : DataGridViewTextBoxCell
    {
        public override void InitializeEditingControl(int rowIndex, object initialFormattedValue,
            DataGridViewCellStyle dataGridViewCellStyle)
        {
            base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
            if(DataGridView.EditingControl is NumericUpDown numeric)
            {
                numeric.Value = Convert.ToDecimal(Value ?? DefaultNewRowValue);
                numeric.Minimum = MinValue;
                numeric.Maximum = MaxValue;
            }
        }

        protected override void OnEnter(int rowIndex, bool throughMouseClick)
        {
            if(throughMouseClick)
            {
                DataGridView.BeginEdit(false);
            }
        }

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

        public override Type ValueType
        {
            get { return typeof(string); }
        }

        public override object DefaultNewRowValue
        {
            get { return 0; }
        }

        private int MinValue { get; set; }
        private int MaxValue { get; set; }

        public void UpdateValues(int minValue, int maxValue)
        {
            MinValue = minValue;
            MaxValue = maxValue;
            ReadOnly = MinValue == MaxValue;
            if(ReadOnly)
            {
                Style.ForeColor = Color.DimGray;
            }
        }
    }

    public class NumericUpDownEditingControl : NumericUpDown, IDataGridViewEditingControl
    {
        public object EditingControlFormattedValue
        {
            get => Value;
            set
            {
                if(value is decimal number)
                {
                    try
                    {
                        Value = number;
                    }
                    catch
                    {
                        Value = 0;
                    }
                }
            }
        }

        public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
        {
            if((context & DataGridViewDataErrorContexts.Parsing) != 0)
            {
                return Value.ToString();
            }
            return EditingControlFormattedValue;
        }

        public decimal MinValue
        {
            get => Minimum;
            set => Minimum = value;
        }

        public decimal MaxValue
        {
            get => Maximum;
            set => Maximum = value;
        }

        public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
        {
            Font = dataGridViewCellStyle.Font;
            ForeColor = dataGridViewCellStyle.ForeColor;
            BackColor = dataGridViewCellStyle.BackColor;
        }

        public int EditingControlRowIndex { get; set; }

        public bool EditingControlWantsInputKey(Keys key, bool datagridviewWantsInputKey)
        {
            switch(key & Keys.KeyCode)
            {
                case Keys.Left:
                case Keys.Up:
                case Keys.Down:
                case Keys.Right:
                case Keys.Home:
                case Keys.End:
                case Keys.PageDown:
                case Keys.PageUp:
                    return true;
                default:
                    return !datagridviewWantsInputKey;
            }
        }

        public void PrepareEditingControlForEdit(bool selectAll)
        {
        }

        public bool RepositionEditingControlOnValueChange => false;

        public DataGridView EditingControlDataGridView { get; set; }

        public bool EditingControlValueChanged { get; set; }

        public Cursor EditingPanelCursor => base.Cursor;

        protected override void OnValueChanged(EventArgs eventargs)
        {
            EditingControlValueChanged = true;
            EditingControlDataGridView.NotifyCurrentCellDirty(true);
            base.OnValueChanged(eventargs);
        }
    }
}

This seems to work:

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)
{
    if(decimal.TryParse(value.ToString(), out var val))
    {
        var ctrl = new NumericUpDown()
        {
            Value = val
        };
        var img = new Bitmap(cellBounds.Width, cellBounds.Height);
        ctrl.DrawToBitmap(img, new Rectangle(0, 0, ctrl.Width, ctrl.Height));
        graphics.DrawImage(img, cellBounds.Location);
    }
    else
    {
        throw new InvalidCastException($"{value} is not decimal type");
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM