Well, I've already done all this once, then when I went to post it, the discussion group kicked me out, so here goes again.
First, I think you need to do a little research on the difference between a BlockTableRecord, and a BlockReference. It has been covered on this discussion group so I'm not going to get into here, especially because I have no idea what your experience level with AutoCAD is.
Kean's comment "This simply tells you how many entities met the selection criteria - it doesn't leave them selected for use by further commands." Means that the entities are not left selected in the editor, there is a selection set created (psr.value) that can be used by code to do other things with the selection, they just don't appear to be selected to the user after function ends.
I have worked up these two quick examples of how to get the objects you want and leave them selected in the editor after your command completes. One piece that is not shown here is the the CommandMethod that is called to use this code must have the "CommandFlags.Redraw" set.
public void selectBlock(string blockName)
{
Database db = HostApplicationServices.WorkingDatabase;
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
using (Transaction trans = db.TransactionManager.StartTransaction())
{
try
{
BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead, false, true);
if (bt.Has(blockName))
{
ObjectId btrid = bt[blockName];
if (!btrid.IsEffectivelyErased)
{
BlockTableRecord btr = (BlockTableRecord)trans.GetObject(btrid, OpenMode.ForRead, false, true);
ObjectIdCollection brefIDs = btr.GetBlockReferenceIds(true, false);
ObjectId[] oids = new ObjectId[brefIDs.Count];
brefIDs.CopyTo(oids, 0);
ed.SetImpliedSelection(oids);
}
}
trans.Commit();
}
catch (System.Exception ex)
{
//
}
}
}
public void selectBlock2(string blockName)
{
Database db = HostApplicationServices.WorkingDatabase;
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
TypedValue[] tvs = new TypedValue[] {
new TypedValue(0, "INSERT"),
new TypedValue(2, blockName)
};
SelectionFilter sf = new SelectionFilter(tvs);
PromptSelectionResult psr = ed.SelectAll(sf);
if (psr.Status == PromptStatus.OK)
{
ed.SetImpliedSelection(psr.Value.GetObjectIds());
}
} I would use the second method, as it does not require a transaction, but the first method does demonstrate something that may be useful for your Explode problem.
You can not call Explode on a BlockTableRecord. You also can not "Select" them using selection methods or filters. There is no graphical representation of a BlockTableRecord.
So you say you have a BlockTableRecord. If all you want is to find out what is in that BlockTableRecord, you can iterate through it's contents with a For Each of DbObject. I am assuming that is not what you want, and that what you want is to Explode the BlockReferences that point to that BlockTableRecord. The first example above shows how to get the ObjectIds of all BlockReferences that point to a particular BlockTableRecord. You can then use those ObjectIds to open each BlockReference and call .ExplodeToOwnerSpace if you want to duplicate the behavior of the AutoCAD Explode command (I'm not sure if you have to erase the original block, or if the API does it for you, but the API does add each of the resultant entities to the owner of the BlockReference), or you can call .Explode and the use the results of that explode to do whatever it is you need to do (In which case you must add the objects to the database or dispose of them, and if you want the original block to be erased you have to do that yourself).
Give that a shot. I'll see if I can find a good article describing the difference between a BlockTableRecord and a BlockReference.
Dave O.