简体   繁体   中英

Adding data to data bound DataGridView (WinForms, C#)

I have 3 tables:

Order (OrderId, columnXY ..)
OrderItem (OrderId, ItemId, Quantity)
Item (ItemId, Name, Price)

The order table is bound to a DataGridView . On selection changed for the order dgv, an orderedItem dgv is populated like this:

view.GetOrderedItemDataGridView().DataSource = dataContext.OrderItemSet.Where(o => o.OrderId == orderId).Select(o => new { o.Item.Id, o.Quantity, o.Item.Price }).ToList();

Upon pressing an AddItemButton , a dialog opens to pick an item, after which the item should be added to the orderedItem dgv:

using (var form = new OrderItemView(dataContext.ItemSet.ToList()))
{
    if (form.ShowDialog() == DialogResult.OK)
    {
        // Add selected item from OrderItemView to orderedItem dgv
    }
    else
    {

    }
}

The changes are supposed to be saved later, by clicking the SaveOrderButton, or canceled by clicking the CancelOrderButton.

void view_SaveOrderClicked(object sender, EventArgs e)
{
    // Get order data
    int customerId = Convert.ToInt32(view.OrderCustomerID);
    order.CustomerId = customerId;
    order.Weight = Convert.ToDouble(view.OrderWeight);
    order.Sum = Convert.ToDecimal(view.OrderSum);
    order.Date = view.OrderDate;
    order.AddressId = dataContext.AddressSet.Where(c => c.CustomerId == customerId && c.IsDeliveryAddress == true)
                                                .Select(a => a.Id).SingleOrDefault();

    if (!orderUpdateMode)
    {
        dataContext.OrderSet.Add(order);
    }
    else
    {
        dataContext.Entry(order).State = EntityState.Modified;
    }

    dataContext.SaveChanges();
}

I can't figure out how to add a new item to the dgv, since I can't add rows directly to a data bound dgv. Also, I'm populating the dgv with an anonymous type, so I can't have a class property to use as data source to which I add the new item. Should I maybe make a new object to fill the dgv, using only the properties I want displayed? I'm retrieving the data the way I do right now so that only certain columns are added to the orderedItem dgv.

How can I solve this problem?

Cheers!

EDIT: When using BindingSource I run into problems because the type I get in the OnSelectionChanged event method of the Order dgv ...

orderedItemsBS.DataSource = dataContext.OrderItemSet.Where(o => o.OrderId == orderId).
Select(o => new { o.Item.Id, o.Item.Name, o.Quantity, o.Item.Price }).ToList();

is not the same as the one I get after selecting an orderItem:

void view_NewOrderItemClicked(object sender, EventArgs e)
{
    using (var form = new OrderItemView(dataContext.ItemSet.ToList()))
    {
        if (form.ShowDialog() == DialogResult.OK)
        {
            var item = new { Id = form.Item.Id, Name = form.Item.Name, Quantity = form.Quantity, Price = form.Item.Price };
            orderedItemsBS.Add(item);
            view.GetOrderedItemDataGridView().DataSource = orderedItemsBS;
        }
    }
}

Also, I don't want to save anything to the db in the NewOrderItemClicked method since the user might press the CancelButton after editing/adding an order.

Either use BindingSource and add items to it (will automatically update DataGridView that is bound to ( tutorial ) or rebind data source after adding:

view.GetOrderedItemDataGridView().DataSource = null; 
view.GetOrderedItemDataGridView().Rows.Clear();
view.GetOrderedItemDataGridView().DataSource = dataContext.OrderItemSet.Where(o => o.OrderId == orderId).Select(o => new { o.Item.Id, o.Quantity, o.Item.Price }).ToList();

After edit:

First of all: do not use anonymous type, create normal class and work with it.

Second:

view.GetOrderedItemDataGridView().DataSource = orderedItemsBS;

this line is not needed, instead add this: orderedItemsBS.ResetBindings(false);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM