Windows Develop Bookmark and Share   
 index > Windows Forms Data Controls and Databinding > DataRepeater DrawItem - How do I access the underlying item data using Entity Framework
 

DataRepeater DrawItem - How do I access the underlying item data using Entity Framework

DbEntities de = new GalleryEntities();
var query = from supplier in de.SupplierSet
select supplier;

dataRepeater1.DataSource = query;

//

private void dataRepeater1_DrawItem(object sender, Microsoft.VisualBasic.PowerPacks.DataRepeaterItemEventArgs e)
{
DataRepeaterItem row = e.DataRepeaterItem;
int inx = row.ItemIndex;
Supplier supplier = <how do I get the data associated with the DataRepeater.Item >
row.BackColor = supplier.balance > 0.0 ? Color.Red : Color.Black;
}
  • Moved byOmegaManMVPThursday, June 04, 2009 4:43 PM (From:Visual C# General)
  •  
Datamast  Wednesday, June 03, 2009 1:02 PM

Hi Datamast,

How are you?

After my further research, I think binding the data to an IQueryable collection makes the updating operations complicated. Furthermore, IQueryable collection does not support index-based insert which makes BindingSource.Insert method fails. To make the update operations work fine and enable the insert action, I bind the data to a List<T> of entities and modify some codes of the corresponding operations like binding, deleting, adding, inserting and the DrawItem event. Here is the detailed code example for your references:

=======================================================================

public partial class Form1 : Form

{

public Form1()

{

InitializeComponent();

// Binding controls

textBox1.DataBindings.Add(new Binding("Text", bs.DataSource, "ID", true));

textBox2.DataBindings.Add(new Binding("Text", bs.DataSource, "Name", true));

}

TestDBEntities entities;

BindingSource bs = new BindingSource();

// Display the Added, Deleted and Modified entity entries

private void DisplayObjectEntries()

{

var entriesAdded = entities.ObjectStateManager.GetObjectStateEntries(EntityState.Added);

Console.WriteLine("Added Entry number: {0}", entriesAdded.Count());

foreach (var entry in entriesAdded)

{

if (entry.IsRelationship)

{

Console.WriteLine("RelationshipEntry {0}, State: {1}",

entry.EntitySet.Name, entry.State);

}

else

{

Invoice customer = entry.Entity as Invoice;

if (customer != null)

{

Console.WriteLine("Invoice {0}, State: {1}",

customer.ID, entry.State);

}

}

}

var entriesDeleted = entities.ObjectStateManager.GetObjectStateEntries(EntityState.Deleted);

Console.WriteLine("Deleted Entry number: {0}", entriesDeleted.Count());

foreach (var entry in entriesDeleted)

{

if (entry.IsRelationship)

{

Console.WriteLine("RelationshipEntry {0}, State: {1}",

entry.EntitySet.Name, entry.State);

}

else

{

Invoice customer = entry.Entity as Invoice;

if (customer != null)

{

Console.WriteLine("Invoice {0}, State: {1}",

customer.ID, entry.State);

}

}

}

var entriesModified = entities.ObjectStateManager.GetObjectStateEntries(EntityState.Modified);

Console.WriteLine("Modified Entry number: {0}", entriesModified.Count());

foreach (var entry in entriesModified)

{

if (entry.IsRelationship)

{

Console.WriteLine("RelationshipEntry {0}, State: {1}",

entry.EntitySet.Name, entry.State);

}

else

{

Invoice customer = entry.Entity as Invoice;

if (customer != null)

{

Console.WriteLine("Invoice {0}, State: {1}",

customer.ID, entry.State);

}

}

}

}

// Bind the data

private void BindData()

{

entities = new TestDBEntities();

var query = from inv in entities.Invoice

select inv;

// Bind the List<Invoice> to the data source

bs.DataSource = query.ToList();

dataRepeater1.DataSource = bs;

}

// Button1 is used to bind the data

private void button1_Click(object sender, EventArgs e)

{

BindData();

}

// Button2 is used to update the database

private void button2_Click(object sender, EventArgs e)

{

// Update the database

try

{

DisplayObjectEntries();

entities.SaveChanges();

}

catch (Exception ex)

{

Console.WriteLine(ex.ToString());

// Rebind the data if exceptions is thrown

BindData();

}

}

// Button3 is used to the data to the certain position

private void button3_Click(object sender, EventArgs e)

{

Invoice inv = new Invoice() { ID = 15, Name = "New Invoice" };

inv.Customer = entities.Customer.Where(c => c.ID == 1).FirstOrDefault();

// Insert the data into BindingSource

bs.Insert(4, inv);

// Add the data to the ObjectContext

entities.AddToInvoice(inv);

// Update the database

try

{

DisplayObjectEntries();

entities.SaveChanges();

}

catch (Exception ex)

{

Console.WriteLine(ex.ToString());

// Rebind the data if exceptions is thrown

BindData();

}

}

// Button4 is used to add new entity in the last

private void button4_Click(object sender, EventArgs e)

{

Invoice inv = new Invoice() { ID = 15, Name = "New Invoice" };

inv.Customer = entities.Customer.Where(c => c.ID == 1).FirstOrDefault();

// Add the data into the BindingSource

bs.Add(inv);

// Add the data to the ObjectContext

entities.AddToInvoice(inv);

// Update the database

try

{

DisplayObjectEntries();

entities.SaveChanges();

}

catch (Exception ex)

{

Console.WriteLine(ex.ToString());

// Rebind the data if exceptions is thrown

BindData();

}

}

// User delete the entity

private void dataRepeater1_UserDeletingItems(object sender, DataRepeaterAddRemoveItemsCancelEventArgs e)

{

try

{

e.Cancel = true;

// Get the entity

Invoice inv = dataRepeater1.BindingContext[dataRepeater1.DataSource].Current as Invoice;

if (inv != null)

{

// Mark the entity as Deleted in ObjectContext

entities.DeleteObject(inv);

// Remove the entity from the BindingSource

bs.Remove(inv);

DisplayObjectEntries();

int result = entities.SaveChanges();

Console.WriteLine("{0} modification performs...", result);

}

}

catch (Exception ex)

{

Console.WriteLine("User Deleting Items...");

Console.WriteLine(ex.ToString());

// Rebind the data if exceptions is thrown

BindData();

}

}

// DrawItem event

private void dataRepeater1_DrawItem(object sender, DataRepeaterItemEventArgs e)

{

DataRepeaterItem row = e.DataRepeaterItem;

int inx = row.ItemIndex;

Invoice inv = bs[inx] as Invoice;

if (inv != null)

{

int id = inv.ID;

row.BackColor = id % 2 == 0 ? Color.Red : Color.Black;

}

}

// User add entity by "Ctrl + N"

private void dataRepeater1_UserAddedItems(object sender, DataRepeaterAddRemoveItemsEventArgs e)

{

int newItemInx = e.ItemIndex;

Invoice inv = bs[newItemInx] as Invoice;

if (inv != null)

{

inv.ID = 15;

inv.Name = "New Invoice";

inv.Customer = entities.Customer.Where(c => c.ID == 1).FirstOrDefault();

}

// Mark the entity as Added in the ObjectContext

entities.AddToInvoice(inv);

DisplayObjectEntries();

// Update the database

try

{

entities.SaveChanges();

}

catch (Exception ex)

{

Console.WriteLine(ex.ToString());

// Rebind the data if exceptions is thrown

BindData();

}

}

}

=======================================================================

You can modify these codes to fit your own design target. Important to note: The insert operation is only for the UI level, after load the data from the database, the order is determined by the data records order in the database.

If you have any questions, please feel free to let me know.

Have a great day!

Best Regards,
Lingzhi


Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
Send us any feedback you have about the help from MSFT at fbmsdn@microsoft.com.
  • Marked As Answer byDatamast Tuesday, June 16, 2009 11:17 PM
  •  
Lingzhi Sun  Monday, June 08, 2009 3:51 PM

Hi Datamast,

Glad to see you!

From your code snippet, you try to retrieve the entity class in order to get the balance property. Using this property, you can modify the back color of each DataRepeaterItem. Please correct me if there is any misunderstanding.

Based on this scenario, here are two workarounds for your references. According to your application condition, you can choose the most appropriate method to use.

1. If the balance property is also displayed in some control like TextBox on the DataRepeater, we can directly retrieve the text on the control. For detail, please see the following code snippet. I used the same data structure in this related thread: http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/e4b869de-dda5-4da8-89ce-d5d36820bf9b.

==========================================================

private void dataRepeater1_DrawItem(object sender, DataRepeaterItemEventArgs e)

{

DataRepeaterItem row = e.DataRepeaterItem;

int inx = row.ItemIndex;

int id = int.Parse(row.Controls["textBoxID"].Text);

row.BackColor = id % 2 == 0 ? Color.Red : Color.Black;

}

==========================================================

2. If the balance property is not showed in the user interface, we need to retrieve the corresponding entity class to get the balance property. The most convenient way is to query the entity by this method BindingSource[ItemIndex]. But it needs us to create a BindingSource object for the DataRepeater and do a little modification when binding the data. For detail, please refer to the following codes:

==========================================================

BindingSource bs = new BindingSource();

private void button1_Click(object sender, EventArgs e)

{

var query = from inv in entities.Invoice

select inv;

bs.DataSource = query;

dataRepeater1.DataSource = bs;

}

private void dataRepeater1_DrawItem(object sender, DataRepeaterItemEventArgs e)

{

DataRepeaterItem row = e.DataRepeaterItem;

int inx = row.ItemIndex;

Invoice inv = bs[inx] as Invoice;

if (inv != null)

{

int id = inv2.ID;

row.BackColor = id % 2 == 0 ? Color.Red : Color.Black;

}

}

==========================================================

If you have any questions, please feel free to let me know.

Have a nice day!

Best Regards,
Lingzhi


Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
Send us any feedback you have about the help from MSFT at fbmsdn@microsoft.com.
Lingzhi Sun  Thursday, June 04, 2009 4:24 AM
The second approach using the DataBinder works nicely.

Additional query: When adding a new Item (AddNew or Ctrl-N), how do I perform an initialisation of the EntityObject.


This code fails :

// Initalially do some binding ...
pk_Supplier.DataBindings.Add(new Binding("Text", query, pk_Supplier.Name, true));
Supplier_Name.DataBindings.Add(new Binding("Text", query, Supplier_Name.Name, true));


// Use the ItemsAdded event to detect the addition of new Item.

private void dataRepeater_ItemsAdded(object sender, DataRepeaterAddRemoveItemsEventArgs e)
{
int newItemInx = e.ItemIndex;
Supplier supplier = bindingSource[newItemInx] as Supplier;

supplier.Supplier_Name = "New Supplier"; // My example chosen initialisation **fails**
}


The new item is 'drawn' with blank Supplier_Name - How do I resolve this

The BindingSource is aware of the new item but the DataSource/Query doesn't and the binding fails. (Blank/default entries)


Take Care

Datamast
Datamast  Thursday, June 04, 2009 4:27 PM

Hi Datamast,

Glad to hear that my approach works nicely for you. For the adding new item question, I recommend you to try handling the UserAddedItems event. Based on my test, initializing the entity object in this event works fine. For detail, please refer to the following code snippet:

==========================================================

private void dataRepeater1_UserAddedItems(object sender, DataRepeaterAddRemoveItemsEventArgs e)

{

int newItemInx = e.ItemIndex;

Invoice inv = bs[newItemInx] as Invoice;

if (inv != null)

{

inv.Name = "New Name";

// Other initializing operations

// �/span>

}

}

==========================================================

Have a nice day!

Best Regards,
Lingzhi


Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
Send us any feedback you have about the help from MSFT at fbmsdn@microsoft.com.
Lingzhi Sun  Friday, June 05, 2009 2:49 AM
If the user adds the item (Ctrl-N) it works fine but if dataRepeater.AddNew() if used to create an entry it doesn't get called.

So I added the item to the bindingsource which worked nicely. bindingSource.Add(Object)

But, I then wanted to programatically insert an item at an index. E.g. bindingSource.Insert(index, Object)

Result:
Exception ="The index-based insert operation is not supported on this data binding interface."


May I thank you for your much appreciated help, take care

Datamast
Datamast  Friday, June 05, 2009 9:33 AM

I was wrong : AcceptChanges() results in:

"The changes to the database were committed successfully, but an error occurred while updating the object context.
The ObjectContext might be in an inconsistent state.

Inner exception message:

AcceptChanges cannot continue because the object's key values conflict with another object in the ObjectStateManager.
Make sure that the key values are unique before calling AcceptChanges."

I will try to condense and reproduce the problem.

Datamast
Datamast  Friday, June 05, 2009 12:04 PM

Hi Datamast,

How are you?

After my further research, I think binding the data to an IQueryable collection makes the updating operations complicated. Furthermore, IQueryable collection does not support index-based insert which makes BindingSource.Insert method fails. To make the update operations work fine and enable the insert action, I bind the data to a List<T> of entities and modify some codes of the corresponding operations like binding, deleting, adding, inserting and the DrawItem event. Here is the detailed code example for your references:

=======================================================================

public partial class Form1 : Form

{

public Form1()

{

InitializeComponent();

// Binding controls

textBox1.DataBindings.Add(new Binding("Text", bs.DataSource, "ID", true));

textBox2.DataBindings.Add(new Binding("Text", bs.DataSource, "Name", true));

}

TestDBEntities entities;

BindingSource bs = new BindingSource();

// Display the Added, Deleted and Modified entity entries

private void DisplayObjectEntries()

{

var entriesAdded = entities.ObjectStateManager.GetObjectStateEntries(EntityState.Added);

Console.WriteLine("Added Entry number: {0}", entriesAdded.Count());

foreach (var entry in entriesAdded)

{

if (entry.IsRelationship)

{

Console.WriteLine("RelationshipEntry {0}, State: {1}",

entry.EntitySet.Name, entry.State);

}

else

{

Invoice customer = entry.Entity as Invoice;

if (customer != null)

{

Console.WriteLine("Invoice {0}, State: {1}",

customer.ID, entry.State);

}

}

}

var entriesDeleted = entities.ObjectStateManager.GetObjectStateEntries(EntityState.Deleted);

Console.WriteLine("Deleted Entry number: {0}", entriesDeleted.Count());

foreach (var entry in entriesDeleted)

{

if (entry.IsRelationship)

{

Console.WriteLine("RelationshipEntry {0}, State: {1}",

entry.EntitySet.Name, entry.State);

}

else

{

Invoice customer = entry.Entity as Invoice;

if (customer != null)

{

Console.WriteLine("Invoice {0}, State: {1}",

customer.ID, entry.State);

}

}

}

var entriesModified = entities.ObjectStateManager.GetObjectStateEntries(EntityState.Modified);

Console.WriteLine("Modified Entry number: {0}", entriesModified.Count());

foreach (var entry in entriesModified)

{

if (entry.IsRelationship)

{

Console.WriteLine("RelationshipEntry {0}, State: {1}",

entry.EntitySet.Name, entry.State);

}

else

{

Invoice customer = entry.Entity as Invoice;

if (customer != null)

{

Console.WriteLine("Invoice {0}, State: {1}",

customer.ID, entry.State);

}

}

}

}

// Bind the data

private void BindData()

{

entities = new TestDBEntities();

var query = from inv in entities.Invoice

select inv;

// Bind the List<Invoice> to the data source

bs.DataSource = query.ToList();

dataRepeater1.DataSource = bs;

}

// Button1 is used to bind the data

private void button1_Click(object sender, EventArgs e)

{

BindData();

}

// Button2 is used to update the database

private void button2_Click(object sender, EventArgs e)

{

// Update the database

try

{

DisplayObjectEntries();

entities.SaveChanges();

}

catch (Exception ex)

{

Console.WriteLine(ex.ToString());

// Rebind the data if exceptions is thrown

BindData();

}

}

// Button3 is used to the data to the certain position

private void button3_Click(object sender, EventArgs e)

{

Invoice inv = new Invoice() { ID = 15, Name = "New Invoice" };

inv.Customer = entities.Customer.Where(c => c.ID == 1).FirstOrDefault();

// Insert the data into BindingSource

bs.Insert(4, inv);

// Add the data to the ObjectContext

entities.AddToInvoice(inv);

// Update the database

try

{

DisplayObjectEntries();

entities.SaveChanges();

}

catch (Exception ex)

{

Console.WriteLine(ex.ToString());

// Rebind the data if exceptions is thrown

BindData();

}

}

// Button4 is used to add new entity in the last

private void button4_Click(object sender, EventArgs e)

{

Invoice inv = new Invoice() { ID = 15, Name = "New Invoice" };

inv.Customer = entities.Customer.Where(c => c.ID == 1).FirstOrDefault();

// Add the data into the BindingSource

bs.Add(inv);

// Add the data to the ObjectContext

entities.AddToInvoice(inv);

// Update the database

try

{

DisplayObjectEntries();

entities.SaveChanges();

}

catch (Exception ex)

{

Console.WriteLine(ex.ToString());

// Rebind the data if exceptions is thrown

BindData();

}

}

// User delete the entity

private void dataRepeater1_UserDeletingItems(object sender, DataRepeaterAddRemoveItemsCancelEventArgs e)

{

try

{

e.Cancel = true;

// Get the entity

Invoice inv = dataRepeater1.BindingContext[dataRepeater1.DataSource].Current as Invoice;

if (inv != null)

{

// Mark the entity as Deleted in ObjectContext

entities.DeleteObject(inv);

// Remove the entity from the BindingSource

bs.Remove(inv);

DisplayObjectEntries();

int result = entities.SaveChanges();

Console.WriteLine("{0} modification performs...", result);

}

}

catch (Exception ex)

{

Console.WriteLine("User Deleting Items...");

Console.WriteLine(ex.ToString());

// Rebind the data if exceptions is thrown

BindData();

}

}

// DrawItem event

private void dataRepeater1_DrawItem(object sender, DataRepeaterItemEventArgs e)

{

DataRepeaterItem row = e.DataRepeaterItem;

int inx = row.ItemIndex;

Invoice inv = bs[inx] as Invoice;

if (inv != null)

{

int id = inv.ID;

row.BackColor = id % 2 == 0 ? Color.Red : Color.Black;

}

}

// User add entity by "Ctrl + N"

private void dataRepeater1_UserAddedItems(object sender, DataRepeaterAddRemoveItemsEventArgs e)

{

int newItemInx = e.ItemIndex;

Invoice inv = bs[newItemInx] as Invoice;

if (inv != null)

{

inv.ID = 15;

inv.Name = "New Invoice";

inv.Customer = entities.Customer.Where(c => c.ID == 1).FirstOrDefault();

}

// Mark the entity as Added in the ObjectContext

entities.AddToInvoice(inv);

DisplayObjectEntries();

// Update the database

try

{

entities.SaveChanges();

}

catch (Exception ex)

{

Console.WriteLine(ex.ToString());

// Rebind the data if exceptions is thrown

BindData();

}

}

}

=======================================================================

You can modify these codes to fit your own design target. Important to note: The insert operation is only for the UI level, after load the data from the database, the order is determined by the data records order in the database.

If you have any questions, please feel free to let me know.

Have a great day!

Best Regards,
Lingzhi


Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
Send us any feedback you have about the help from MSFT at fbmsdn@microsoft.com.
  • Marked As Answer byDatamast Tuesday, June 16, 2009 11:17 PM
  •  
Lingzhi Sun  Monday, June 08, 2009 3:51 PM
Hi Lingzhi

I am very well, hope you had an excellent weekend?

Can you provide a code snippet that returns a DataRepeaterItem for a given index so that it can be 'Selected'

public void SelectRowByIndex(int inx)
{
bindingSource.Position = inx;
DataRepeaterItem row = dataRepeater1.Items [inx]; // missing collection of DataRepeaterItems?? - how is this effected?
row.Select(); // Validating event will now occur when control loses focus
}

--------------
The code snippet entities.AddTo Invoice(invoice) if omitted is still updating the Database when SaveChanges() is called. What does it do?


Thank you for your considerable effort. I have implemented an Ilist instead of Iqueryable and will confirm success when I have cross checked my code. Looking very hopeful :)

Have fun

Datamast
Datamast  Tuesday, June 09, 2009 11:15 AM

Hi Datamast,

Yes, I have a wonderful weekend with my family. Thank you! J

Glad to hear that my code example helps. To select the certain item of the DataRepeater, how about using this code snippet?

========================================================

private void SelectRowByIndex(int index)

{

bs.Position = index;

dataRepeater1.CurrentItemIndex = index;

}

========================================================

I added the code �strong style="">entities.AddToInvoice(inv);� because I want to make sure the certain entity object has been added to the ObjectContext. The method is similar with the methods entities.AddToSupplier or entities.AddObject. I think without this line of code, the entity is also updated correctly is because the relationship of the entity has been added to the ObjectContext. So if we bind some entities without any relationships with other entities, I think this line of code is necessary.

Besides, I think this series articles on MSDN about the DataRepeater is really helpful, http://msdn.microsoft.com/en-us/library/cc488280.aspx.

Have a nice day!

Best Regards,
Lingzhi




Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
Send us any feedback you have about the help from MSFT at fbmsdn@microsoft.com.
Lingzhi Sun  Wednesday, June 10, 2009 7:20 AM
Hi Lingzhi

I had already tried datarepeater1.CurrentItemIndex and it 'marks' the item as current but the DataRepeaterItem does not receive focus and consequently doesn't fire a
Validating event when I click on a different row. I'm using that event to check that the 'Data Row' is valid. Consequently if I add a new row then click on a different row
I wish to (perhaps) remove the new row deeming it unwanted or refocus it. No ValidatingEvent - no can do.

Have fun

Datamast
Datamast  Wednesday, June 10, 2009 8:55 AM

Hi Datamast,

How about these codes? J

=======================================================

private void SelectRowByIndex(int index)

{

bs.Position = index;;

dataRepeater1.CurrentItemIndex = index;

dataRepeater1.CurrentItem.Select();

}

=======================================================

Can the code snippet fix the problem?

Best Regards,
Lingzhi


Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
Send us any feedback you have about the help from MSFT at fbmsdn@microsoft.com.
Lingzhi Sun  Wednesday, June 10, 2009 9:07 AM
Hi Lingzhi

Yes it does work - thank you, think I was having a mental blip - couldn't spot the wood for the trees! (Never thought of selecting each index, I was thinking where are the array indices?)

How do you prevent a single entity from updating?

I.E. I have a DataRepeater with 10 Rows populated but I add an eleventh (blank) row by adding new Entity() to the bindingsource. The blank row appears.

We know the 11th entry is invalid but need to call entityContext.SaveChanges() because (say) the user has pressed a commit button. (I don't want to use
the commitButton Click event to do this, in fact I will be using a ValidatingEvent for real as a part of auto-committing. The example still holds.)
How can we exclude the 11th Entity given that the apps program has determined it to be invalid at this stage?
Is there an entityContext.RemoveFromEntityTracking (eleventhObject)?
Then can you entityContext.Add(eleventhObject) when the application program is satisfied that it may be valid once its details are filled in?

At what point should I start a new thread?
Have fun

Datamast





Datamast  Wednesday, June 10, 2009 4:41 PM

Hi Datamast,

How are you?

For the first question, the DataRepeater does not have the property (like Items) to get all the DataRepeaterItems collection it owns. So I used the CurrentItemIndex and CuttentItem in my last reply.

For the question, how to prevent a single entity from updating? Based on the scenario that you mentioned, I have such a workaround for your references:

When the new item is added (bs.Add, bs.Insert or pressing “Ctrl + N�, we handle the ItemsAdded event of the DataRepeater and add the Validating event handler to the newly added DataRepeaterItem. In the Validating event handler, we can check whether the new entity is valid and then update the database when the item is losing focus. Here are some related codes, all the adding update action should be in the DataRepeaterItem_Validating event.

===============================================================

private void dataRepeater1_ItemsAdded(object sender, DataRepeaterAddRemoveItemsEventArgs e)

{

int index = e.ItemIndex;

dataRepeater1.CurrentItemIndex = index;

DataRepeaterItem row = dataRepeater1.CurrentItem;

row.Select();

row.Validating += new CancelEventHandler(this.dataRepeaterItem_Validating);

}

private void dataRepeaterItem_Validating(object sender, CancelEventArgs e)

{

Invoice inv = bs[bs.Position] as Invoice;

if (inv != null)

{

if (inv.ID == 15)

{

// Remove the invalid entity

bs.Remove(inv);

entities.DeleteObject(inv);

}

DisplayObjectEntries();

// Update the database

try

{

entities.SaveChanges();

}

catch (Exception ex)

{

Console.WriteLine(ex.ToString());

// Rebind the data if exceptions is thrown

BindData();

}

}

}

===============================================================

For the last question, what point to create a new thread? Generally, in MSDN forums, one thread is discussing one question. So if you have some new questions to ask, please create a new thread, so that more community members can both help and benefit from the threads.

Have a nice day, Datamast!

Best Regards,
Lingzhi


Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
Send us any feedback you have about the help from MSFT at fbmsdn@microsoft.com.
Lingzhi Sun  Thursday, June 11, 2009 8:03 AM
Hi Lingzhi

I am fine (my son was 18 this month so its been hectic). Hope you and your family are well?

The problem is that your code snippet entities.DeleteObject (inv) also sets foreign keys (in reality the AssociationSet) to null .

E.g. having created a partial Invoice entry and setting the supplier foreign key to the chosen supplier, DeleteObject wipes that association and the partially
filled in invoice entry suddenly loses some of its data i.e. its supplier.

Secondly, the approach exposes a logical inconsistancy ....

entities.DeleteObject (entity); // Fine - fantastic

entities.AddObject (entitySetName_as_string , entity); // Yuck!!! I hate hardcoding anything as a string. (Refactoring fails...)

It should at least be the instance of the EntitySet you are adding to. E.g. entities.AddObject(entities.SupplierSet, supplier);

Ideally, I would rather it be entity.AddObject(entity) and let the EF add it to the SET associated with the Entity.

(P.S. I willl have to use AddObject to put the partial entry back after the SaveChanges, hopefully preserving foreign keys)

Can I avoid this horrid hardcoding?

Take care

Datamast

Datamast  Thursday, June 11, 2009 10:15 AM

Hi Datamast,

Congratulations! You son is a man now. J

Sorry if I misunderstand your meaning in my last post. I thought you want to put the validating codes (checking both properties values and relationships) in some validating event.

Then I think the DataRepeaterItem’s Validating event does not meet our demand. How about putting the validating codes in DataRepeater’s Validating event? So that we can check the entire set of the entities.

Besides, we can also consider putting the validating part in the entity’s events, such as On***Changing, On***Changed events and the ObjectContext.SavingChanges event.

For the AddObject method, alternatively we can use the AddTo*** methods, like AddToInvoice(Invoice), AddToCustomer(Customer), etc.

Have a nice weekend!

Best Regards,
Lingzhi



Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
Send us any feedback you have about the help from MSFT at fbmsdn@microsoft.com.

Lingzhi Sun  Friday, June 12, 2009 12:12 PM

Hi Datamast,

How are you?

How is the problem going now? Could you please tell me whether my suggestions help?

Have a nice day!

Best Regards,
Lingzhi


Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
Send us any feedback you have about the help from MSFT at fbmsdn@microsoft.com.
Lingzhi Sun  Monday, June 15, 2009 8:26 AM
Hi Lingzhi

Hope you and your family had a nice weekend?
I reality I am extending the DataRepeater class to create what I have called a VisualList. It has IList, IEnumerable properties, BindingSource and a DataRepeater.

It means that writing complex data input for 'transactional' processes becomes extremely easy. E.g. invoicing product lines, booking in of purchases, stock entry.
Therefore the AddTo functionality is having to operate on <T> types. Where these types are of System.Data.Entity then the EF is automatically updated.

Datamast
Datamast  Monday, June 15, 2009 3:36 PM

Hi Datamast,

Thank you! My last weekend is really wonderful.

For the VisualList that you are designing, I think it is definitely cool. I will be very happy if I can help you on the problems, so feel free to create new threads to discuss it, if you have any questions.

I think here is the reason why the AddObject method is different from the DeleteObject method: When an entity is deleted, it has already been traced by the ObjectStateManager. So from the entity’s key, we can detect the certain entity with the help of ObjectStateManager. While if an new entity is added, the object has never been traced, the ObjectStateManager cannot know which collection the entity should belong to. So we have to set the entity set name in the AddObject method. (These information can be retrieved if we research the implementation of the ObjectContext via .NET Reflector.)

By default, the entity’s class name is the table name in the SQL Server and the entity set name in ObjectContext is the same as the entity name, like the Invoice that I am always using. However, if we modify the entity’s name, like Invoice à MyInvoice, the entity set name in ObjectContext will be modified to MyInvoiceSet. So one potential workaround to call AddObject dynamically is using .NET Reflection to get the object type name. Here is the code snippet for your references:

The ObjectContext is defined as partial class, so we can add new methods to this class.

======================================================
public void AddObject(object obj)

{

string name = obj.GetType().Name;

try

{

base.AddObject(name, obj);

}

catch (InvalidOperationException)

{

try

{

base.AddObject(name + "Set", obj);

}

catch (Exception ex)

{

MessageBox.Show(ex.Message);

}

}

}

======================================================

But, if the entity information is modified greatly in the entity data model, this method is not appropriate.


Have a nice day, Datamast!

Best Regards,
Lingzhi


Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
Send us any feedback you have about the help from MSFT at fbmsdn@microsoft.com.
Lingzhi Sun  Tuesday, June 16, 2009 7:39 AM

Hi Datamast,

How are you?

Thank you very much for marking my reply as the answer.

If you create a new thread to ask some other questions, please feel free to let me know. I will be really happy to see whether I can help. J

Here is my mail address: v-micsun@microsoft.online.com (remove “online�

Have a nice day!

Best Regards,
Lingzhi


Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
Send us any feedback you have about the help from MSFT at fbmsdn@microsoft.com.
Lingzhi Sun  Wednesday, June 17, 2009 7:42 AM

You can use google to search for other answers

Custom Search

More Threads

• Sorting a DataGridView Programatically
• Suppress update to datagridview
• Problem in Populating datagridview with designed columns
• Relationship and currency manager
• How to create image and to give link in datagrid
• NoNullAllowedException when trying to cancel out of new record add
• ErrorProvider showing Property Errors Twice.
• Building a custom cell/column for the DataGridView
• Databinding to a related table
• Tables & Views - Have to submit this wednesday :(