【发布时间】:2015-01-26 17:58:15
【问题描述】:
我有一个数据库,其中的字段以分钟为单位表示时间。但是在我的 datagridview 中,我不想将时间显示为 hh:mm。例如。 130 分钟应显示为 02:10,编辑时带有蒙版文本框。我创建了一个 DataGridView 并将一个名为 MaskedTextboxMinutes 的自定义列类放在时间列中,并创建了一个用于处理编辑的自定义控件。我只在编辑单元格时显示文本框,在不编辑时(我不希望在不编辑单元格时显示文本框)。当不编辑原始 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);
}
}
最好的问候 汉斯·米林...
【问题讨论】:
-
查看 DataGridView CellParsing 和 CellFormatting 事件。您可以格式化显示的值,但基础数据不会更改。
-
@Crowcoder - 我知道这是一篇很老的帖子,但我很难找到在 VB.NET 中工作的类似内容,即使在我转换之后也是如此。另外,我是这类事情的新手,并不太了解这些代码。我希望你能引导我朝着正确的方向前进,因为我可以复制/粘贴到我项目中的类模块中并让它工作? (可能不是,嗯)
-
@braX,这太模糊了。考虑问你自己的问题。提供完整的错误详情和a mcve。
标签: c# winforms datagridview datatable maskedtextbox