ผมต้องการให้ผู้ใช้งานใส่สูตรในเซลล์ จากนั้นก็คำนวณ ได้เลย ครับ
โดย DataGridView ผูกอยู่กับ BindingSource
ผมลองทำ 3 แบบ คือ
1. ใช้ DataGridViewTextBoxColumn และ CellEndEdit
[Spoil] คลิกเพื่อดูข้อความที่ซ่อนไว้private void aLS_F_711DataGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
DataGridView dgv = sender as DataGridView;
if (dgv[1, e.RowIndex].Value == null || string.IsNullOrEmpty(dgv[1, e.RowIndex].Value.ToString()))
{
dgv[1, e.RowIndex].Value = f711Item;
}
if (e.ColumnIndex == 3)
{
string value = dgv.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString();
if (value.StartsWith("="))
{
string expression = value.Substring(1); // เอาเฉพาะส่วนที่ต้องการคำนวณ
// คำนวณ
DataTable table = new DataTable();
var result = table.Compute(expression, "");
MessageBox.Show(result.ToString());
dgv[3, e.RowIndex].Value = result;
}
}
}
ผลคือ พิมพ์แล้ว คลิกอะไรไม่ได้เลย ต้องปิดโปรแกรมอย่างเดียว
แต่ถ้าไม่ผูกกับ BindingSource ก็ใช้ได้ปกติ
2. เขียนคลาส ขึ้นมาใช้งาน
[Spoil] คลิกเพื่อดูข้อความที่ซ่อนไว้#region _DataGridViewCalColumn
public class DataGridViewCalColumn : DataGridViewColumn
{
public DataGridViewCalColumn()
: base(new DataGridViewCalCell())
{
}
public override DataGridViewCell CellTemplate
{
get { return base.CellTemplate; }
set
{
if (!(value is DataGridViewCalCell))
throw new InvalidCastException("Must be a DataGridViewCalCell");
base.CellTemplate = value;
}
}
}
internal class DataGridViewCalCell : DataGridViewTextBoxCell
{
public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
{
base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
}
protected override void OnLeave(int rowIndex, bool throughMouseClick)
{
base.OnLeave(rowIndex, throughMouseClick);
if ((!object.ReferenceEquals(this.Value, DBNull.Value)) && (this.Value != null))
{
string value = this.Value.ToString();
string expression = (value.StartsWith("=")) ? value.Substring(1) : value; // เอาเฉพาะส่วนที่ต้องการคำนวณ
var result = new DataTable().Compute(expression, "");
this.Value =result.ToString();
}
if (DataGridView != null)DataGridView.EndEdit();
}
public override Type EditType => typeof(DataGridViewCalEdit);
public override Type ValueType => typeof(string);
}
internal class DataGridViewCalEdit : TextBox, IDataGridViewEditingControl
{
private DataGridView dataGridViewControl;
private bool valueIsChanged = false;
private int rowIndexNum;
public object EditingControlFormattedValue
{
get => Text;
set
{
if (value is string str)
Text = str;
}
}
public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context) => Text;
public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle) => Font = dataGridViewCellStyle.Font;
public int EditingControlRowIndex
{
get => rowIndexNum;
set => rowIndexNum = value;
}
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 false;
}
}
public void PrepareEditingControlForEdit(bool selectAll)
{
}
public bool RepositionEditingControlOnValueChange => false;
public DataGridView EditingControlDataGridView
{
get => dataGridViewControl;
set => dataGridViewControl = value;
}
public bool EditingControlValueChanged
{
get => valueIsChanged;
set => valueIsChanged = value;
}
public Cursor EditingControlCursor => Cursor;
Cursor IDataGridViewEditingControl.EditingPanelCursor => EditingControlCursor;
protected override void OnTextChanged(EventArgs e)
{
valueIsChanged = true;
EditingControlDataGridView.NotifyCurrentCellDirty(true);
base.OnTextChanged(e);
}
}
#endregion
ใช้ DataGridViewCalColumn ก็ค้างเหมือนเดิม ถ้าไม่ผูกกับ BindingSource ก็ใช้ได้ปกติ ก็ใช้ได้เหมือนเดิม
C# WinApp DataGridView ต้องการใส่การคำนวณใน DataGridView ครับ
โดย DataGridView ผูกอยู่กับ BindingSource
ผมลองทำ 3 แบบ คือ
1. ใช้ DataGridViewTextBoxColumn และ CellEndEdit
[Spoil] คลิกเพื่อดูข้อความที่ซ่อนไว้
ผลคือ พิมพ์แล้ว คลิกอะไรไม่ได้เลย ต้องปิดโปรแกรมอย่างเดียว
แต่ถ้าไม่ผูกกับ BindingSource ก็ใช้ได้ปกติ
2. เขียนคลาส ขึ้นมาใช้งาน
[Spoil] คลิกเพื่อดูข้อความที่ซ่อนไว้
ใช้ DataGridViewCalColumn ก็ค้างเหมือนเดิม ถ้าไม่ผูกกับ BindingSource ก็ใช้ได้ปกติ ก็ใช้ได้เหมือนเดิม