我有一个DataGridView,我绑定到POCO。我有数据绑定工作正常。但是,我添加了一个组合框列,我希望每行都有所不同。具体来说,我有一个购买物品网格,其中一些有尺寸(如成人XL,成人L)和其他项目不规模(如汽车磁铁。)
基本上我想要改变的是数据网格中组合框列的DATA SOURCE。可以这样做吗?
我可以将哪些事件挂钩,以便我可以更改每行的某些列的属性?可接受的替代方法是在用户单击或标记到行中时更改属性。这是什么事?
赛斯
修改
我需要更多关于这个问题的帮助。随着Triduses帮助我很接近,但我需要更多的信息。
首先,根据问题,CellFormatting事件确实是更改组合框列的DataSource的最佳/唯一事件。我问,因为我正在做一些相当资源/数据密集的事情,而不仅仅是格式化单元格。
其次,只需将鼠标悬停在单元格上即可调用cellformatting事件。我尝试在 if-block 中设置FormattingApplied属性,然后在 if-test 中检查它,但是返回了一个奇怪的错误消息。我理想的情况是,我会为每一行应用更改组合框的数据源一次,然后用它完成。
最后,为了设置组合框colunm的数据源,我必须能够将if块内的Cell转换为DataGridViewComboBoxColumn类型,以便我可以用行填充它或设置数据源或其他东西。这是我现在的代码。
Private Sub ProductsDataGrid_CellFormatting(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellFormattingEventArgs) Handles ProductsDataGrid.CellFormatting
If e.ColumnIndex = ProductsDataGrid.Columns("SizeDGColumn").Index Then ' AndAlso Not e.FormattingApplied Then
Dim product As LeagueOrderProductInfo = DirectCast(ProductsDataGrid.Rows(e.RowIndex).DataBoundItem, LeagueOrderProductInfo)
Dim sizes As LeagueOrderProductSizeList = product.ProductSizes
sizes.RemoveSizeFromList(_parentOrderDetail.SizeID)
'WHAT DO I DO HERE TO FILL THE COMBOBOX COLUMN WITH THE sizes collection.
End If
End Sub
请帮忙。我完全陷入困境,这个任务项目应该花费一个小时,现在我已经超过了4个小时。顺便说一句,我也愿意通过采取一个完全不同的方向来解决这个问题(只要我可以快速完成。)
赛斯
答案 0 :(得分:3)
不幸的是,没有一个。您将要使用的是CellFormatting event。
这将触发每个单元格,但你可以通过检查单元格的列索引来确定你是否在正确的列中,然后如果你在列中你想要工作就可以做你的逻辑用。
如果您决定在选择行而不是显示行时更改它,则可以改为使用RowEnter。
以下是如何使用此事件的代码示例。这个将列设置为包含图像。
Private Sub dgActiveOccurrences_CellFormatting(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellFormattingEventArgs) Handles dgActiveOccurrences.CellFormatting
If e.ColumnIndex = dgActiveOccurrences.Columns("colActiveUnreadFlag").Index Then
Dim occ As Occurrence = DirectCast(dgActiveOccurrences.Rows(e.RowIndex).DataBoundItem, Occurrence)
If occ.LastReadBy <> OccurrenceSession.Self.UserManager.MyStaffRecord.StaffId Then
e.Value = My.Resources.Icon_UnreadFlag
End If
End If
End Sub
答案 1 :(得分:2)
我没有采用捕捉事件的方式来改变每行的组合框中的显示值...看看这种方法(示例),它非常简单易用,并且完全符合您的要求IMHO:
使用两个简单属性(名称,类型)声明一个Item类
创建一个包含两列的DataGridView(一个用于Name,第二个用于Type,其中ColumnType = DataGridViewComboBoxColumn和dataPropertyName = Type)
将“我的假设”poco's列表“附加”到DataGridView
然后只通过你的行集合循环一次; 抓取该行的DataGridViewComboBoxColumn ; 根据您对该行中poco的标准更改其项目属性。
我把它留给你抓住特定行的poco,或者从行中的硬编码列中读取一些属性......
以下是一些示例代码:
namespace DataGridViewCustomComboboxItemsPerRow
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
List<int> types = new List<int>();
List<Item> items = new List<Item>();
Item item;
for (int i = 0; i < 100; i++)
{
item = new Item();
item.Name = "Item" + i.ToString();
item.Type = i;
items.Add(item);
types.Add(i);
}
//typeDataGridViewComboBoxColumn.DataSource = types;
itemBindingSource.DataSource = items;
}
private void Form1_Shown(object sender, EventArgs e)
{
DataGridViewComboBoxCell dgvc;
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
dgvc = (DataGridViewComboBoxCell)dataGridView1.Rows[i].Cells[1];
// Your CUSTOM code here, I just did some stupid thing here...
dgvc.Items.Add(i - 1);
dgvc.Items.Add(i);
dgvc.Items.Add(i + 1);
}
}
}
public class Item
{
private string _name;
private int _type;
public string Name
{
get { return _name; }
set { _name = value; }
}
public int Type
{
get { return _type; }
set { _type = value; }
}
}
}
代码在C#中,但非常基本,所以我想它不会在VB.NET中引起问题。而且这段代码实际上是一次性循环(O(n))来为不同的行配置你的组合而不是完成它。
希望这会有所帮助。的Joep。
答案 2 :(得分:0)
我不确定这对你是否可行。
您可以在dataGridView1_DataBindingComplete
事件
foreach (DataGridViewRow var in dataGridView1.Rows)
{
if (var.Cells[0] is DataGridViewComboBoxCell)
{
(var.Cells[0] as DataGridViewComboBoxCell).Items.Add("first col values");
}
if (var.Cells[1] is DataGridViewComboBoxCell)
{
(var.Cells[1] as DataGridViewComboBoxCell).Items.Add("second col values");
}
}
答案 3 :(得分:0)
如果无法向此网格添加行,则可以使用事件DataBindingComplete,当网格完成数据绑定时会触发此事件,如果可以添加行,则必须使用此事件NewRowNeeded此事件如果单击网格底部的新行,则会触发 你不会担心多次填充相同的组合
答案 4 :(得分:0)
您可以使用CellBeginEdit事件执行此操作。处理事件,检查正在编辑的列是否是DataGridViewComboBox列并更改组合框中的项目。
如果将数据源绑定到组合框,则可能无效。我只是尝试手动添加项目列表:
void grid_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
{
if (grid.Columns[e.ColumnIndex].Name == "MyComboColumn")
{
// get the value of a different cell in this row that will be used to determine which values are in the combobox
string other_value = grid[0, e.RowIndex].Value.ToString();
// get the combobox cell being edited
DataGridViewComboBoxCell cell = (DataGridViewComboBoxCell)grid[e.ColumnIndex, e.RowIndex];
// update the list of items in the combobox
cell.Items.Clear();
if (other_value == "something")
cell.Items.AddRange(new object[] { "Value1", "Value2" });
else
cell.Items.AddRange(new object[] { "Value3", "Value4" });
}
}
注意:此代码未经测试,我现在不在我的开发机器上。