private void DoAfterListShuffle()
        {
            if (myPositionManager != null)
            {
                try
                {
                    if (ListShuffleEnding != null)
                    {
                        // Fill in the current positions for each position tracker
                        // by asking the associated lists where the object is now.
                        if (myPositionHead != null)
                        {
                            NODEPOSITIONTRACKER.UpdateEndPositions(myPositionHead);
                        }

                        // Now that all of the PositionTracker structures are up
                        // to date, notify the listeners to update their selections.
                        ListShuffleEnding(this, myPositionManager);
                    }
                }
                finally
                {
                    NODEPOSITIONTRACKER.DetachAll(ref myPositionHead);
                    myPositionManager = null;
                }
            }
        }
 private void ListShuffleEnding(object sender, PositionManagerEventArgs manager)
 {
     var lbstate = myShuffleTracker;
     myShuffleTracker = null;
     if (lbstate != null)
     {
         var cache = manager.RetrievePositions(this, myMctree != null);
         if (cache != null)
         {
             lbstate.Inner.ApplyPositionTrackerData(cache);
             lbstate.Inner.Restore(this);
         }
     }
 }
 private void DoBeforeListShuffle()
 {
     DelayTurnOffRedraw();
     // Begin shuffling list by retrieving PositionTracker arrays from
     // all of our listeners (if any).
     Debug.Assert(myPositionManager == null); // Should be long gone at this point
     // Check after as well, Before is useless without an After listener
     if (ListShuffleBeginning != null
         && ListShuffleEnding != null)
     {
         var positionManager = new PositionManagerEventArgs(this);
         NODEPOSITIONTRACKER ntHead = null;
         NODEPOSITIONTRACKER ntLast = null;
         TREENODE tnParent;
         int relativeRow;
         int relativeColumn;
         try
         {
             ListShuffleBeginning(this, positionManager);
             foreach (PositionTracker[] trackerSet in positionManager)
             {
                 var upper = trackerSet.GetUpperBound(0);
                 for (var i = trackerSet.GetLowerBound(0); i <= upper; ++i)
                 {
                     if (TrackPosition(ref trackerSet[i], out tnParent, out relativeRow, out relativeColumn))
                     {
                         if (ntHead != null)
                         {
                             if (NODEPOSITIONTRACKER.Add(tnParent, trackerSet, i, relativeRow, relativeColumn, ref ntLast))
                             {
                                 continue;
                             }
                         }
                         else if (NODEPOSITIONTRACKER.Add(tnParent, trackerSet, i, relativeRow, relativeColumn, ref ntHead))
                         {
                             ntLast = ntHead;
                             continue;
                         }
                     }
                     ClearPositionTracker(ref trackerSet[i]);
                 }
             }
         }
         catch
         {
             // Errors from the branches are caught during add, so this is a
             // failure on our side. Make sure that all position tracking information
             // is fully detached from the TREENODE objects before continuing. 
             if (ntHead != null)
             {
                 NODEPOSITIONTRACKER.DetachAll(ref ntHead);
             }
             throw;
         }
         finally
         {
             // We made it all the way, go ahead and record the results
             // with this object. Note that we record our results even if
             // the position head is null so that the user gets a ListShuffleEnding
             // event if nothing was tracked successfully. This lets the listener
             // reduce the set of operations they do during other insert and delete
             // notifications while a position manager is active.
             myPositionManager = positionManager;
             myPositionHead = ntHead;
         }
     }
 }
 private void ListShuffleBeginning(object sender, PositionManagerEventArgs manager)
 {
     myShuffleTracker = new ListBoxStateTrackerClass(this);
     var cache = myShuffleTracker.Inner.GetPositionTrackers();
     if (cache != null)
     {
         manager.StorePositions(cache, this, myMctree != null);
     }
 }