You're trying to do two different things here. Firstly you're trying to find a document, and secondly you're trying to change things based upon it. The first stage in the process is simply to clarify the code you already have, e.g.
(Note this takes into account previous comments that the computed indexes in the original code are not needed. The exact same type of split into two methods could be done whether or not the computed indexes are required, and it would still improve the original code.)
public void FindAndDisplayEventDocWithoutEAN(HandOverDoc handOverDoc)
{
var eventDoc = FindEventDocWithoutEAN(handOverDoc);
if (eventDoc != null)
{
Display(eventDoc);
}
}
public EventDoc FindEventDocWithoutEAN(HandOverDoc handOverDoc)
{
foreach(ItemDoc itemDoc in handOverDoc.Assignment.Items)
foreach(ItemDetailDoc detail in itemDoc.Details)
foreach(EventDoc eventDoc in detail.Events)
if(!eventDoc.HasEAN)
return eventDoc;
return null;
}
public void Display(EventDoc eventDoc)
{
HideShowPanels(pMatch);
txt_EAN.Text = String.Empty;
lbl_Match_ArtName.Text = itemDoc.Name;
lbl_ArtNr.Text = itemDoc.Number;
lbl_unitDesc.Text = eventDoc.Description;
m_tempItemNr = itemNr;
m_tempEventNr = eventDocNr;
txt_EAN.Focus();
}
Once you've done that, you should be able to see that one method is a query over the main document, and the other is a method to display the results of the query. This is what's known as the single responsibility principle, where each method does one thing, and is named after what it does.
The transformation of the nested foreach loops to a linq query is now almost trivial. Compare the method below with the method above, and you can see how mechanical it is to translate nested foreach loops into a linq query.
public EventDoc FindEventDocWithoutEAN(HandOverDoc handOverDoc)
{
return (from itemDoc in handOverDoc.Assignment.Items
from detail in itemDoc.Details
from eventDoc in detail.Events
where !eventDoc.HasEAN
select eventDoc).FirstOrDefault();
}