繁体   English   中英

在datagridview中以小时和分钟的形式显示和编辑数据表中的int列

[英]Display and edit int column from datatable as hours and minutes in datagridview

我有一个数据库,其中的字段表示以分钟为单位的时间。 但是在我的datagridview中,我不会将时间显示为hh:mm。 例如130分钟应显示为02:10,并在编辑时显示带遮罩的文本框。 我创建了一个DataGridView,并在时间列中放置了一个名为MaskedTextboxMinutes的custum列类,并创建了用于处理编辑的自定义控件。 我只在编辑单元格时显示文本框,而在不编辑时才显示(我不希望在不编辑单元格时显示文本框)。 不编辑时,以分钟为单位显示原始int字段值(例如130)。 创建了MaskedTextboxMinutes,以分钟为输入和输出,但显示为hh:mm。 问题是,我应该在哪里放置一些代码以覆盖列的显示方式? 我想避免覆盖onpaint。

这些是我的MaskedTextBoxMinutes和DataGridView单元格,列和控件的类:

时间课:

class Time
{
    public int Hours { get; set; }
    public int Minutes { get; set; }
    public override string ToString()
    {
        string h = Hours.ToString("D2");
        if (h.Length == 1)
            h = "0" + h;
        return Hours.ToString("D2") + ":" + Minutes.ToString("D2");
    }

    public static Time Parse(string time)
    {
        Time t = new Time();
        t.Hours = 0;
        t.Minutes = 0;
        if (!string.IsNullOrEmpty(time))
        {
            time = time.Replace("\r", "").Replace("\n", "").Replace("\t", "").Replace(" ", "").Trim(); // Remove whitespace chars
            if (time.IndexOf(",") >= 0 || time.IndexOf(".") >= 0 || time.IndexOf(":") < 0)
                throw new Exception("Not a valid time: " + time + " should be format hh:mm");
            string[] hm = time.Split(':');
            if (string.IsNullOrEmpty(hm[0]))
                hm[0] = "0";
            if (string.IsNullOrEmpty(hm[1]))
                hm[1] = "0";
            t.Hours = int.Parse(hm[0]);
            t.Minutes = int.Parse(hm[1]);
        }
        return t;
    }

    public static Time FromMinutes(int minutes)
    {
        int hours = minutes / 60;
        minutes -= (hours * 60);
        Time t = new Time();
        t.Hours = hours;
        t.Minutes = minutes;
        return t;
    }

    public int getTotalMinutes()
    {
        return Hours * 60 + Minutes;
    }

}

类MaskedTextBoxMinutes:

    class MaskedTextBoxMinutes : MaskedTextBox
    {
        public override string Text
        {
            get
            {
                Time t = Time.Parse(base.Text);
                return t.getTotalMinutes().ToString();
            }
            set
            {
                int minutes = 0;
                int.TryParse(value, out minutes);
                base.Text = Time.FromMinutes(minutes).ToString();
            }
        }
    }

类MaksedEditControl:

class MaskedEditingControl : MaskedTextBoxMinutes, IDataGridViewEditingControl
{
    private DataGridView dataGridViewControl;
    private bool valueIsChanged = false;
    private int rowIndexNum;

    public MaskedEditingControl() : base()
    {
        this.Mask = "00:00";
        this.InsertKeyMode = InsertKeyMode.Overwrite;
    }

    public object EditingControlFormattedValue
    {
        get { return this.Text; }
        set { this.Text = value.ToString(); }
    }
    public bool EditingControlWantsInputKey(Keys key, bool dataGridViewWantsInputKey)
    {
        return true;
    }
    public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
    {
        return this.Text;
    }
    public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
    {

        this.Font = dataGridViewCellStyle.Font;
        this.ForeColor = dataGridViewCellStyle.ForeColor;
        this.BackColor = dataGridViewCellStyle.BackColor;
    }
    public int EditingControlRowIndex
    {
        get { return rowIndexNum; }
        set { rowIndexNum = value; }
    }
    public void PrepareEditingControlForEdit(bool selectAll)
    {
        // No preparation needs to be done.
    }
    public bool RepositionEditingControlOnValueChange
    {
        get { return false; }
    }
    public DataGridView EditingControlDataGridView
    {
        get { return dataGridViewControl; }
        set { dataGridViewControl = value; }
    }

    public bool EditingControlValueChanged
    {
        get { return valueIsChanged; }
        set { valueIsChanged = value; }
    }
    public Cursor EditingControlCursor
    {
        get { return base.Cursor; }
    }
    Cursor IDataGridViewEditingControl.EditingPanelCursor
    {
        get { return EditingControlCursor; }
    }
    protected override void OnTextChanged(System.EventArgs e)
    {
        // Notify the DataGridView that the contents of the cell have changed.
        valueIsChanged = true;
        if (this.EditingControlDataGridView!=null)
          this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
        base.OnTextChanged(e);
    }
}

类MaskedEditColumn:

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

    private MaskedEditCell MaskedEditCellTemplate
    {
        get { return this.CellTemplate as MaskedEditCell; }
    }
}

类MaskedEditCell:

public class MaskedEditCell : DataGridViewTextBoxCell
{
    public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
    {
        // Set the value of the editing control to the current cell value.
        base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
        MaskedEditColumn mecol = (MaskedEditColumn)OwningColumn;
        MaskedEditingControl ctl = (MaskedEditingControl)DataGridView.EditingControl;
        ctl.Text = this.Value.ToString();
    }
    public override Type EditType
    {
        // Return the type of the editing contol that CalendarCell uses.
        get { return typeof(MaskedEditingControl); }
    }
    public override Type ValueType
    {
        // Return the type of the value that CalendarCell contains.
        get { return typeof(string); }
    }
    public override object DefaultNewRowValue
    {
        // Use the current date and time as the default value.
        get { return ""; }
    }
    protected override void Paint(System.Drawing.Graphics graphics, System.Drawing.Rectangle clipBounds, System.Drawing.Rectangle cellBounds, int rowIndex, System.Windows.Forms.DataGridViewElementStates cellState, object value, object formattedValue, string errorText, System.Windows.Forms.DataGridViewCellStyle cellStyle, System.Windows.Forms.DataGridViewAdvancedBorderStyle advancedBorderStyle,
    System.Windows.Forms.DataGridViewPaintParts paintParts)
    {
        base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle,
        paintParts);
    }
}

此致Hans Milling ...

感谢Crowcoder,我通过使用CellFormatting事件解决了它:

    private void dgvTidsregistrering_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
    {
        DataGridView dgv = (DataGridView)sender;
        if (dgv.Columns[e.ColumnIndex].CellType == typeof(MaskedEditCell))
        {
            double minutes = 0;
            if (e.Value is double)
                minutes = Convert.ToInt32(e.Value);
            else
            {
                if (e.Value == DBNull.Value)
                    minutes = 0;
                else
                    double.TryParse((string)e.Value, out minutes);
            }
            Time t = Time.FromMinutes((int)minutes);
            e.Value = t.ToString();
        }
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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