我有这样的类:
public class PricingRecord
{
private string _name;
private float[] _prices;
public PricingRecord(string name, float[] prices)
{
_name = name;
_prices = prices;
}
[DisplayName("Name")]
public string PricingName => _name;
public float[] Prices => _prices;
}
我想将"价格"映射到 DataGridView 中的"价格 1"、"价格 2"等列。我可以显示列,但不知道如何使映射工作。
这是主窗口:
public partial class MainForm : Form
{
private int _numPricingColumns;
private BindingList<PricingRecord> _records;
public MainForm()
{
InitializeComponent();
SetupPricingData();
SetupGridView();
}
private void SetupPricingData()
{
_records = new BindingList<PricingRecord>();
for (int i = 0; i < 100; i++)
{
var pricing = new PricingRecord($"Name {i + 1}", new [] { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f });
_records.Add(pricing);
}
_numPricingColumns = _records[0].Prices.Length;
GridView.DataSource = _records;
}
private void SetupGridView()
{
//GridView.AutoGenerateColumns = false;
//DataGridViewColumn column = new DataGridViewTextBoxColumn
//{
// Name = "Name",
// DataPropertyName = "PricingName"
//};
//GridView.Columns.Add(column);
for (int i = 0; i < _numPricingColumns; i++)
{
DataGridViewColumn column = new DataGridViewTextBoxColumn
{
Name = $"Price {i + 1}",
DataPropertyName = $"Price{i + 1}"
};
GridView.Columns.Add(column);
}
}
}
如果我不使用 BindingView,我可以手动设置它,但是我必须自己维护行和列。我想使用 BindingView,但这似乎不支持将许多列映射到数组。
我发现我可以通过绘制它们来获取要处理的定价列。我需要的用途是只读的,所以这是我现在的解决方案:
private void OnCellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
for (int i = 0; i < _numPricingColumns; i++)
{
var name = $"Price {i + 1}";
var column = GridView.Columns[name];
if (column.Index == e.ColumnIndex && e.RowIndex >= 0)
{
var row = GridView.Rows[e.RowIndex];
var record = row.DataBoundItem as PricingRecord;
if (record != null)
{
var selected = (e.State & DataGridViewElementStates.Selected) != 0;
using (var brush = new SolidBrush(selected ? e.CellStyle.SelectionForeColor : e.CellStyle.ForeColor))
{
e.PaintBackground(e.ClipBounds, selected);
e.Graphics.DrawString(record.Prices[i].ToString("N"), e.CellStyle.Font, brush,
e.CellBounds.X + 2.0f, e.CellBounds.Y + 2.0f, StringFormat.GenericDefault);
e.Handled = true;
}
}
}
}
}
事实证明,
一个更快、更灵活的解决方案是删除 BindingList 并直接戳网格中的单元格。将数组字段映射到多个列的需求变得毫无意义,因为它是手动完成的。