我想在DataGridView
中添加公式单元格。是否有任何自定义DataGridView
来执行此操作?
示例:
grid[4, column].Text = string.Format("=MAX({0}6:{0}{1})", columnAsString, grid.RowCount);
答案 0 :(得分:7)
在很多情况下,很多情况下数据实际上并不在public static IWebElement WaitAndFindElement(Func<IWebDriver, IWebElement> expectedCondtions, int timeoutInSeconds)
{
WebDriverWait webDriverWait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds));
return webDriverWait.Until(expectedCondtions);
}
//Now you can call above function as
IWebElement el = WaitAndFindElement(ExpectedConditions.ElementExists(by), timeoutInSeconds);
中,而在其他地方如IWebElement el = WaitAndFindElement(ExpectedConditions.elementToBeClickable(by), timeoutInSeconds);
或某种类型的集合(如DataGridView
)。控件只是向用户显示数据视图。
有几种方法可以按照你想要的方式做某事。对于这两种情况,数据实际上都位于DataTable
。
可以为List<T>
分配Expression。请参阅链接,了解所支持的表达式,关键字,运算符和函数的类型。以下内容将为某些行创建基于表达式的列到多个DataTable
:
DataColumn
添加一些随机数据后,以及一个空行,Quantity * Price
将为您维护这些列。这可能就像您可能希望的那样:如果用户(或代码)更改了dtSample = new DataTable();
dtSample.Columns.Add(new DataColumn("Item", typeof(string)));
dtSample.Columns.Add(new DataColumn("Quantity", typeof(int)));
dtSample.Columns.Add(new DataColumn("Price", typeof(decimal)));
dtSample.Columns.Add(new DataColumn("Sale", typeof(decimal)));
// assign expression using the col names
dtSample.Columns[3].Expression = "(Quantity * Price)";
或DataTable
单元格的值,则Quantity
列内容会自动更新。 (图像在第二种方法之后)。
Price
在行级别工作。对于像TOTALS行这样的东西,没有全行/逐表的计数器部分 - 这是因为数据通常来自Sale
。添加计算的行可能会意外地将新数据添加到该源(如数据库)。但是在代码中做起来并不难:
与给出的DGV Expressions
答案类似,您可以回复来自DataSource
的事件,例如CellFormatting
。在那里,您可以执行任何操作并更新表格。
DataTable
然后,在该事件中,代码计算在最后一行中显示的超过所有单位平均值。在某些情况下,您可以使用RowChanged
的{{1}}方法。与...create table and columns
...populate table
// hook up event
dtSample.RowChanged += RowChanged;
不同,它不会自动更新,as shown in this answer更新可能会很笨拙。
使用DataTable中的类型化数据,可以非常轻松地执行计算以响应事件:
Compute()
“销售”列通过DataTable
自动维护,这意味着您无法手动对该列执行任何操作。
底部的整体平均价格也“自动”更新,不同之处在于我们必须编写一些代码才能这样做。
答案 1 :(得分:3)
是否有任何自定义DataGridView可以执行此操作?
偏离主题,但如果您正在寻找自定义控件,请查看Free .NET Spreadsheet Control。它还支持formula。
如果您可以选择编写计算代码
如果编写用于计算的代码是您的选项,要根据某些其他单元格的值计算单元格的值,您可以使用CellFormatting
事件DataGridView
并将计算逻辑放在那里。同时处理CellEndEdit
并致电InvalidateCell
或Invalidate
以强制更新参考单元格中每个单元格后的值。
以下是一个例子:
void Form1_Load(object sender, EventArgs e)
{
Random r = new Random();
var dt = new DataTable();
dt.Columns.Add("A", typeof(int));
dt.Columns.Add("B", typeof(int));
for (int i = 0; i < 10; i++)
dt.Rows.Add(r.Next(100));
grid.DataSource = dt;
grid.CellFormatting += grid_CellFormatting;
grid.CellEndEdit += grid_CellEndEdit;
}
void grid_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
grid.Invalidate();
}
void grid_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
var grid = sender as DataGridView;
var parameterColumnName = "A"; //Parameter column name
var start = 0; //Start row index for formula
var end = grid.RowCount - 1; //End row index for formula
var resultRowIndex = 0; //Result row index
var resultColumnName = "B"; //Result column name
if (e.RowIndex == resultRowIndex &&
grid.Columns[e.ColumnIndex].Name == resultColumnName)
{
var list = Enumerable.Range(start, end - start + 1)
.Select(i => grid.Rows[i].Cells[parameterColumnName].Value)
.Where(x => x != null && x != DBNull.Value)
.Cast<int>();
if (list.Any())
e.Value = list.Max();
}
}
注意强>
解决方案不仅限于DataTable
,无论您使用DataSource
DataGridView
,它都可以使用,您可以在此解决方案中使用任何类型的数据源。
答案 2 :(得分:2)
不,您正在处理纯数据字符串,您需要在后台运行一个线程来进行计算并相应地更新UI。
答案 3 :(得分:0)
您可以尝试的几件事:
处理单元格值更改事件,以检测计算中使用的单元格之一何时更改并计算适当的值。诸如此类(在新项目中尝试)
Public Class Form1
Private WithEvents DGV As New DataGridView
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
DGV.SetBounds(20, 50, 400, 200)
Controls.Add(DGV)
DGV.Columns.Add("Qty", "Qty")
DGV.Columns.Add("Price", "Price")
DGV.Columns.Add("Total", "Total")
DGV.Columns("Total").ReadOnly = True
DGV.RowCount = 5
End Sub
Private Sub DGV_CellValueChanged(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DGV.CellValueChanged
If e.ColumnIndex = DGV.Columns("Qty").Index Or e.ColumnIndex = DGV.Columns("Price").Index Then
DGV("Total", e.RowIndex).Value = CInt(DGV("Qty", e.RowIndex).Value) * CDbl(DGV("Price", e.RowIndex).Value)
End If
End Sub
End Class
或者不是直接将文件读取到datagridview而是将其读入数据表并将网格绑定到数据表。然后,您可以在数据表中添加一个表达式列以进行计算。像这样:
Public Class Form1
Private WithEvents DGV As New DataGridView
Private DT As New DataTable
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
DGV.SetBounds(20, 50, 400, 200)
Controls.Add(DGV)
DT.Columns.Add("Qty", GetType(Int32))
DT.Columns.Add("Price", GetType(Double))
DT.Columns.Add("Total", GetType(Double))
DT.Columns("Total").Expression = "Qty * Price"
DGV.DataSource = DT
End Sub
End Class