在datagridview中显示和编辑数据表中的int列作为小时和分钟

时间:2015-01-23 12:34:02

标签: c# winforms datagridview datatable maskedtextbox

我有一个数据库,其中的字段代表以分钟为单位的时间。但在我的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;
    }

}

Class 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);
    }
}

Class 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; }
    }
}

Class 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);
    }
}

祝你好运   汉斯米林......

1 个答案:

答案 0 :(得分:0)

感谢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();
        }
    }