OnEdgeOrVertexTableSelectionChange
(
Boolean bChangeInEdgeTable
)
{
AssertValid();
Sheets1And2Helper oSheets1And2Helper = bChangeInEdgeTable ?
m_oEdgeWorksheet.Sheets1And2Helper :
m_oVertexWorksheet.Sheets1And2Helper;
if (IgnoreTableSelectionChange(oSheets1And2Helper))
{
return;
}
m_bIgnoreSelectionEvents = true;
try
{
// (The following comments are for the bChangeInEdgeTable=true
// case.
// Get an array of unique row IDs for all edge rows that have at
// least one cell selected.
ICollection <Int32> oSelectedRowIDs =
oSheets1And2Helper.GetSelectedRowIDs();
// Select those edges (and possibly their adjacent vertices) in the
// TaskPane. This will cause the TaskPane.SelectionChangedInGraph
// event to fire, but this class will ignore it because
// m_bIgnoreSelectionEvents is currently set to true.
if (bChangeInEdgeTable)
{
m_oTaskPane.SetSelectedEdgesByRowID(oSelectedRowIDs);
}
else
{
m_oTaskPane.SetSelectedVerticesByRowID(oSelectedRowIDs);
}
// The selection in the vertex table may now be out of sync with
// the TaskPane. Ideally, the vertex table would be updated right
// now. However, you can't select rows in a worksheet that isn't
// active. As a workaround, set a flag that will cause the
// selection in the vertex table to be updated the next time the
// vertex worksheet is activated.
//
// It would be possible to avoid deferring the selection by turning
// off screen updating and temporarily selecting the vertex
// worksheet. Selecting a worksheet is slow, however, even with
// screen updating turned off. It takes about 250ms on a fast
// machine. That's too slow to keep up with the user if he is
// scrolling through a table with the down-arrow key, for example.
if (bChangeInEdgeTable)
{
m_bUpdateVertexSelectionOnActivation = true;
}
else
{
m_bUpdateEdgeSelectionOnActivation = true;
}
// Selecting an edge or vertex invalidates any selected groups.
m_bUpdateGroupSelectionOnActivation = true;
// Enable the "set visual attribute" buttons in the Ribbon.
m_oThisWorkbook.EnableSetVisualAttributes();
}
catch (COMException)
{
// A user reported a bug in which Application.Intersect() throws a
// COMException with an HRESULT of 0x800AC472.
// (Application.Intersect() gets called indirectly by
// OnSelectionChangedInTable().) The bug occurred while switching
// windows. I couldn't reproduce the bug, but the following post
// suggests that the HRESULT, which is VBA_E_IGNORE, occurs when an
// object model call is made while the object model is "suspended."
//
// http://social.msdn.microsoft.com/forums/en-US/vsto/thread/
// 9168f9f2-e5bc-4535-8d7d-4e374ab8ff09/
//
// Other posts also mention that it can occur during window
// switches.
//
// I can't reproduce the bug and I'm not sure of the root cause,
// but catching and ignoring the error should lead to nothing worse
// than a mouse click being ignored.
//
// Update, May 2012:
//
// ExcelUtil.TryGetIntersection() now retries the
// Application.Intersect() call if it fails with a COMException.
// If it fails repeatedly, the exception will eventually get
// rethrown here.
}
catch (Exception oException)
{
ErrorUtil.OnException(oException);
}
finally
{
m_bIgnoreSelectionEvents = false;
}
}