If you have  create a custom web part ListviewByQuery API, you will not be able to get the ECB menu.

   listView = new ListViewByQuery();
   listView.ID = "ListViewByQuery1";
   listView.List = List;
   this.Controls.Add(listView);

If you try to open the ECB menu you will receive a error message :-

"The item is no longer available. It may have been deleted by another user. Click "OK' to refresh the page."

Problem here seems to be with *AJAX Type* menu rendering.  The problem happens in CORE.js file where we call into the *FetchEcbInfo* function.  Here, we read the *itemTable* object that’s in the page and pick up the *tagName* of context we are working on.  In AJAX rendering, we look for this tagName to be *DIV*.  However, for the web part using *ListViewByQuery* control, this tagName seems to be *TABLE* and thus this problem.

To work-around,  we have to create a customcore.js and reference it  using ScriptLink control to defer CORE.js and inject a customCore.js file with all the original CORE.js file content Details here: http://msdn.microsoft.com/en-us/library/cc768565.aspx. Change the value of *tagName* to *DIV* and set it back to *TABLE*.  Here’s that particular code snippet from a debug JS file:

div.innerHTML = strInner;

// change introduced by Navdeep Madan

tagName = "DIV";

var tabs = div.getElementsByTagName(tagName);

tagName = "TABLE";

var tab;

The highlighted statements above are the modifications required.  This seems to ensure that the *tabs* variable has the correct table nodes that it’s looking for. 

Note: The above code snippet is from a CORE.debug.js file.  The same modifications in CORE.js file would be like this:

h = "DIV"; for (var i = j.getElementsByTagName(h), d, e = 0; e < i.length; e++) { d = i[e]; if (d.id == f) break } h = "TABLE"; if (e == i.length)