Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / Core / CSharp / System / Windows / EventRoute.cs / 1 / EventRoute.cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using MS.Utility;
using SR=MS.Internal.PresentationCore.SR;
using SRID=MS.Internal.PresentationCore.SRID;
using MS.Internal;
namespace System.Windows
{
///
/// Container for the route to be followed
/// by a RoutedEvent when raised
///
///
/// EventRoute constitues
/// a non-null
/// and
/// an ordered list of (target object, handler list)
/// pairs
///
///
/// It facilitates adding new entries to this list
/// and also allows for the handlers in the list
/// to be invoked
///
public sealed class EventRoute
{
#region Construction
///
/// Constructor for given
/// the associated
///
///
/// Non-null to be associated with
/// this
///
public EventRoute(RoutedEvent routedEvent)
{
if (routedEvent == null)
{
throw new ArgumentNullException("routedEvent");
}
_routedEvent = routedEvent;
// Changed the initialization size to 16
// to achieve performance gain based
// on standard app behavior
_routeItemList = new FrugalStructList(16);
_sourceItemList = new FrugalStructList(16);
}
#endregion Construction
#region External API
///
/// Adds this handler for the
/// specified target to the route
///
///
/// NOTE: It is not an error to add a
/// handler for a particular target instance
/// twice (handler will simply be called twice).
///
///
/// Target object whose handler is to be
/// added to the route
///
///
/// Handler to be added to the route
///
///
/// Flag indicating whether or not the listener wants to
/// hear about events that have already been handled
///
public void Add(object target, Delegate handler, bool handledEventsToo)
{
if (target == null)
{
throw new ArgumentNullException("target");
}
if (handler == null)
{
throw new ArgumentNullException("handler");
}
RouteItem routeItem = new RouteItem(target, new RoutedEventHandlerInfo(handler, handledEventsToo));
_routeItemList.Add(routeItem);
}
///
/// Invokes all the handlers that have been
/// added to the route
///
///
/// NOTE: If the
/// of the associated
/// is
/// the last handlers added are the
/// last ones invoked
/// However if the
/// of the associated
/// is ,
/// the last handlers added are the
/// first ones invoked
///
///
///
/// that raised the RoutedEvent
///
///
/// that carry
/// all the details specific to this RoutedEvent
///
internal void InvokeHandlers(object source, RoutedEventArgs args)
{
InvokeHandlersImpl(source, args, false);
}
internal void ReInvokeHandlers(object source, RoutedEventArgs args)
{
InvokeHandlersImpl(source, args, true);
}
private void InvokeHandlersImpl(object source, RoutedEventArgs args, bool reRaised)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (args == null)
{
throw new ArgumentNullException("args");
}
if (args.Source == null)
{
throw new ArgumentException(SR.Get(SRID.SourceNotSet));
}
if (args.RoutedEvent != _routedEvent)
{
throw new ArgumentException(SR.Get(SRID.Mismatched_RoutedEvent));
}
// Check RoutingStrategy to know the order of invocation
if (args.RoutedEvent.RoutingStrategy == RoutingStrategy.Bubble ||
args.RoutedEvent.RoutingStrategy == RoutingStrategy.Direct)
{
int endSourceChangeIndex = 0;
// If the RoutingStrategy of the associated is
// Bubble the handlers for the last target
// added are the last ones invoked
// Invoke class listeners
for (int i=0; i<_routeItemList.Count; i++)
{
// Query for new source only if we are
// past the range of the previous source change
if (i >= endSourceChangeIndex)
{
// Get the source at this point in the bubble route and also
// the index at which this source change seizes to apply
object newSource = GetBubbleSource(i, out endSourceChangeIndex);
// Set appropriate source
// The first call to setsource seems redundant
// but is necessary because the source could have
// been modified during BuildRoute call and hence
// may need to be reset to the original source.
// Note: we skip this logic if reRaised is set, which is done when we're trying
// to convert MouseDown/Up into a MouseLeft/RightButtonDown/Up
if(!reRaised)
{
if (newSource == null)
args.Source=source;
else
args.Source=newSource;
}
}
// Invoke listeners
if( TraceRoutedEvent.IsEnabled )
{
TraceRoutedEvent.Trace(
TraceEventType.Start,
TraceRoutedEvent.InvokeHandlers,
_routeItemList[i].Target,
args,
args.Handled );
}
_routeItemList[i].InvokeHandler(args);
if( TraceRoutedEvent.IsEnabled )
{
TraceRoutedEvent.Trace(
TraceEventType.Stop,
TraceRoutedEvent.InvokeHandlers,
_routeItemList[i].Target,
args,
args.Handled );
}
}
}
else
{
int startSourceChangeIndex = _routeItemList.Count;
int endTargetIndex =_routeItemList.Count-1;
int startTargetIndex;
// If the RoutingStrategy of the associated is
// Tunnel the handlers for the last target
// added are the first ones invoked
while (endTargetIndex >= 0)
{
// For tunnel events we need to invoke handlers for the last target first.
// However the handlers for that individual target must be fired in the right order.
// Eg. Class Handlers must be fired before Instance Handlers.
object currTarget = _routeItemList[endTargetIndex].Target;
for (startTargetIndex=endTargetIndex; startTargetIndex>=0; startTargetIndex--)
{
if (_routeItemList[startTargetIndex].Target != currTarget)
{
break;
}
}
for (int i=startTargetIndex+1; i<=endTargetIndex; i++)
{
// Query for new source only if we are
// past the range of the previous source change
if (i < startSourceChangeIndex)
{
// Get the source at this point in the tunnel route and also
// the index at which this source change seizes to apply
object newSource = GetTunnelSource(i, out startSourceChangeIndex);
// Set appropriate source
// The first call to setsource seems redundant
// but is necessary because the source could have
// been modified during BuildRoute call and hence
// may need to be reset to the original source.
if (newSource == null)
args.Source=source;
else
args.Source=newSource;
}
if( TraceRoutedEvent.IsEnabled )
{
TraceRoutedEvent.Trace(
TraceEventType.Start,
TraceRoutedEvent.InvokeHandlers,
_routeItemList[i].Target,
args,
args.Handled );
}
// Invoke listeners
_routeItemList[i].InvokeHandler(args);
if( TraceRoutedEvent.IsEnabled )
{
TraceRoutedEvent.Trace(
TraceEventType.Stop,
TraceRoutedEvent.InvokeHandlers,
_routeItemList[i].Target,
args,
args.Handled );
}
}
endTargetIndex = startTargetIndex;
}
}
}
///
/// Pushes the given node at the top of the stack of branches.
///
///
/// If a node in the tree has different visual and logical,
/// FrameworkElement will store the node on this stack of
/// branches. If the route ever returns to the same logical
/// tree, the event source will be restored.
///
/// NOTE: This method needs to be public because it is used
/// by FrameworkElement.
///
///
/// The node where the visual parent is different from the logical
/// parent.
///
///
/// The source that is currently being used, and which should be
/// restored when this branch is popped off the stack.
///
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Advanced)]
public void PushBranchNode(object node, object source)
{
BranchNode branchNode = new BranchNode();
branchNode.Node = node;
branchNode.Source = source;
BranchNodeStack.Push(branchNode);
}
///
/// Pops the given node from the top of the stack of branches.
///
///
/// If a node in the tree has different visual and logical,
/// FrameworkElement will store the node on this stack of
/// branches. If the route ever returns to the same logical
/// tree, the event source will be restored.
///
/// NOTE: This method needs to be public because it is used
/// by FrameworkElement.
///
///
/// The node where the visual parent was different from the
/// logical parent.
///
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Advanced)]
public object PopBranchNode()
{
if (BranchNodeStack.Count == 0)
return null;
BranchNode branchNode = BranchNodeStack.Pop();
return branchNode.Node;
}
///
/// Peeks the given node from the top of the stack of branches.
///
///
/// If a node in the tree has different visual and logical,
/// FrameworkElement will store the node on this stack of
/// branches. If the route ever returns to the same logical
/// tree, the event source will be restored.
///
/// NOTE: This method needs to be public because it is used
/// by FrameworkElement.
///
///
/// The node where the visual parent was different from the
/// logical parent.
///
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Advanced)]
public object PeekBranchNode()
{
if (BranchNodeStack.Count == 0)
return null;
BranchNode branchNode = BranchNodeStack.Peek();
return branchNode.Node;
}
///
/// Peeks the given source from the top of the stack of branches.
///
///
/// If a node in the tree has different visual and logical,
/// FrameworkElement will store the node on this stack of
/// branches. If the route ever returns to the same logical
/// tree, the event source will be restored.
///
/// NOTE: This method needs to be public because it is used
/// by FrameworkElement.
///
///
/// The source that was stored along with the node where the
/// visual parent was different from the logical parent.
///
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Advanced)]
public object PeekBranchSource()
{
if (BranchNodeStack.Count == 0)
return null;
BranchNode branchNode = BranchNodeStack.Peek();
return branchNode.Source;
}
#endregion External API
#region Operations
// Return associated RoutedEvent
internal RoutedEvent RoutedEvent
{
get {return _routedEvent;}
set { _routedEvent = value; }
}
// A BranchNode indicates a point in the tree where the logical and
// visual structure might diverge. When building a route, we store
// this branch node for every logical link we find. Along with the
// node where the possible divergence occurred, we store the source
// that the event should use. This is so that the source of an
// event will always be in the logical tree of the element handling
// the event.
private struct BranchNode
{
public object Node;
public object Source;
}
// Branch nodes are stored on a stack, which we create on-demand.
private Stack BranchNodeStack
{
get
{
if (_branchNodeStack == null)
{
_branchNodeStack = new Stack(1);
}
return _branchNodeStack;
}
}
// Add the given source to the source item list
// indicating what the source will be this point
// onwards in the route
internal void AddSource(object source)
{
int startIndex = _routeItemList.Count;
_sourceItemList.Add(new SourceItem(startIndex, source));
}
// Determine what the RoutedEventArgs.Source should be, at this
// point in the bubble. Also the endIndex output parameter tells
// you the exact index of the handlersList at which this source
// change ceases to apply
private object GetBubbleSource(int index, out int endIndex)
{
// If the Source never changes during the route execution,
// then we're done (just return null).
if (_sourceItemList.Count == 0)
{
endIndex = _routeItemList.Count;
return null;
}
// Similarly, if we're not to the point of the route of the first Source
// change, simply return null.
if (index < _sourceItemList[0].StartIndex)
{
endIndex = _sourceItemList[0].StartIndex;
return null;
}
// See if we should be using one of the intermediate
// sources
for (int i=0; i<_sourceItemList.Count -1; i++)
{
if (index >= _sourceItemList[i].StartIndex &&
index < _sourceItemList[i+1].StartIndex)
{
endIndex = _sourceItemList[i+1].StartIndex;
return _sourceItemList[i].Source;
}
}
// If we get here, we're on the last one,
// so return that.
endIndex = _routeItemList.Count;
return _sourceItemList[_sourceItemList.Count -1].Source;
}
// Determine what the RoutedEventArgs.Source should be, at this
// point in the tunnel. Also the startIndex output parameter tells
// you the exact index of the handlersList at which this source
// change starts to apply
private object GetTunnelSource(int index, out int startIndex)
{
// If the Source never changes during the route execution,
// then we're done (just return null).
if (_sourceItemList.Count == 0)
{
startIndex = 0;
return null;
}
// Similarly, if we're past the point of the route of the first Source
// change, simply return null.
if (index < _sourceItemList[0].StartIndex)
{
startIndex = 0;
return null;
}
// See if we should be using one of the intermediate
// sources
for (int i=0; i<_sourceItemList.Count -1; i++)
{
if (index >= _sourceItemList[i].StartIndex &&
index < _sourceItemList[i+1].StartIndex)
{
startIndex = _sourceItemList[i].StartIndex;
return _sourceItemList[i].Source;
}
}
// If we get here, we're on the last one, so return that.
startIndex = _sourceItemList[_sourceItemList.Count -1].StartIndex;
return _sourceItemList[_sourceItemList.Count -1].Source;
}
///
/// Cleanup all the references within the data
///
internal void Clear()
{
_routedEvent = null;
_routeItemList.Clear();
if (_branchNodeStack != null)
{
_branchNodeStack.Clear();
}
_sourceItemList.Clear();
}
#endregion Operations
#region Data
private RoutedEvent _routedEvent;
// Stores the routed event handlers to be
// invoked for the associated RoutedEvent
private FrugalStructList _routeItemList;
// Stores the branching nodes in the route
// that need to be backtracked while
// augmenting the route
private Stack _branchNodeStack;
// Stores Source Items for separated trees
private FrugalStructList _sourceItemList;
#endregion Data
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using MS.Utility;
using SR=MS.Internal.PresentationCore.SR;
using SRID=MS.Internal.PresentationCore.SRID;
using MS.Internal;
namespace System.Windows
{
///
/// Container for the route to be followed
/// by a RoutedEvent when raised
///
///
/// EventRoute constitues
/// a non-null
/// and
/// an ordered list of (target object, handler list)
/// pairs
///
///
/// It facilitates adding new entries to this list
/// and also allows for the handlers in the list
/// to be invoked
///
public sealed class EventRoute
{
#region Construction
///
/// Constructor for given
/// the associated
///
///
/// Non-null to be associated with
/// this
///
public EventRoute(RoutedEvent routedEvent)
{
if (routedEvent == null)
{
throw new ArgumentNullException("routedEvent");
}
_routedEvent = routedEvent;
// Changed the initialization size to 16
// to achieve performance gain based
// on standard app behavior
_routeItemList = new FrugalStructList(16);
_sourceItemList = new FrugalStructList(16);
}
#endregion Construction
#region External API
///
/// Adds this handler for the
/// specified target to the route
///
///
/// NOTE: It is not an error to add a
/// handler for a particular target instance
/// twice (handler will simply be called twice).
///
///
/// Target object whose handler is to be
/// added to the route
///
///
/// Handler to be added to the route
///
///
/// Flag indicating whether or not the listener wants to
/// hear about events that have already been handled
///
public void Add(object target, Delegate handler, bool handledEventsToo)
{
if (target == null)
{
throw new ArgumentNullException("target");
}
if (handler == null)
{
throw new ArgumentNullException("handler");
}
RouteItem routeItem = new RouteItem(target, new RoutedEventHandlerInfo(handler, handledEventsToo));
_routeItemList.Add(routeItem);
}
///
/// Invokes all the handlers that have been
/// added to the route
///
///
/// NOTE: If the
/// of the associated
/// is
/// the last handlers added are the
/// last ones invoked
/// However if the
/// of the associated
/// is ,
/// the last handlers added are the
/// first ones invoked
///
///
///
/// that raised the RoutedEvent
///
///
/// that carry
/// all the details specific to this RoutedEvent
///
internal void InvokeHandlers(object source, RoutedEventArgs args)
{
InvokeHandlersImpl(source, args, false);
}
internal void ReInvokeHandlers(object source, RoutedEventArgs args)
{
InvokeHandlersImpl(source, args, true);
}
private void InvokeHandlersImpl(object source, RoutedEventArgs args, bool reRaised)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (args == null)
{
throw new ArgumentNullException("args");
}
if (args.Source == null)
{
throw new ArgumentException(SR.Get(SRID.SourceNotSet));
}
if (args.RoutedEvent != _routedEvent)
{
throw new ArgumentException(SR.Get(SRID.Mismatched_RoutedEvent));
}
// Check RoutingStrategy to know the order of invocation
if (args.RoutedEvent.RoutingStrategy == RoutingStrategy.Bubble ||
args.RoutedEvent.RoutingStrategy == RoutingStrategy.Direct)
{
int endSourceChangeIndex = 0;
// If the RoutingStrategy of the associated is
// Bubble the handlers for the last target
// added are the last ones invoked
// Invoke class listeners
for (int i=0; i<_routeItemList.Count; i++)
{
// Query for new source only if we are
// past the range of the previous source change
if (i >= endSourceChangeIndex)
{
// Get the source at this point in the bubble route and also
// the index at which this source change seizes to apply
object newSource = GetBubbleSource(i, out endSourceChangeIndex);
// Set appropriate source
// The first call to setsource seems redundant
// but is necessary because the source could have
// been modified during BuildRoute call and hence
// may need to be reset to the original source.
// Note: we skip this logic if reRaised is set, which is done when we're trying
// to convert MouseDown/Up into a MouseLeft/RightButtonDown/Up
if(!reRaised)
{
if (newSource == null)
args.Source=source;
else
args.Source=newSource;
}
}
// Invoke listeners
if( TraceRoutedEvent.IsEnabled )
{
TraceRoutedEvent.Trace(
TraceEventType.Start,
TraceRoutedEvent.InvokeHandlers,
_routeItemList[i].Target,
args,
args.Handled );
}
_routeItemList[i].InvokeHandler(args);
if( TraceRoutedEvent.IsEnabled )
{
TraceRoutedEvent.Trace(
TraceEventType.Stop,
TraceRoutedEvent.InvokeHandlers,
_routeItemList[i].Target,
args,
args.Handled );
}
}
}
else
{
int startSourceChangeIndex = _routeItemList.Count;
int endTargetIndex =_routeItemList.Count-1;
int startTargetIndex;
// If the RoutingStrategy of the associated is
// Tunnel the handlers for the last target
// added are the first ones invoked
while (endTargetIndex >= 0)
{
// For tunnel events we need to invoke handlers for the last target first.
// However the handlers for that individual target must be fired in the right order.
// Eg. Class Handlers must be fired before Instance Handlers.
object currTarget = _routeItemList[endTargetIndex].Target;
for (startTargetIndex=endTargetIndex; startTargetIndex>=0; startTargetIndex--)
{
if (_routeItemList[startTargetIndex].Target != currTarget)
{
break;
}
}
for (int i=startTargetIndex+1; i<=endTargetIndex; i++)
{
// Query for new source only if we are
// past the range of the previous source change
if (i < startSourceChangeIndex)
{
// Get the source at this point in the tunnel route and also
// the index at which this source change seizes to apply
object newSource = GetTunnelSource(i, out startSourceChangeIndex);
// Set appropriate source
// The first call to setsource seems redundant
// but is necessary because the source could have
// been modified during BuildRoute call and hence
// may need to be reset to the original source.
if (newSource == null)
args.Source=source;
else
args.Source=newSource;
}
if( TraceRoutedEvent.IsEnabled )
{
TraceRoutedEvent.Trace(
TraceEventType.Start,
TraceRoutedEvent.InvokeHandlers,
_routeItemList[i].Target,
args,
args.Handled );
}
// Invoke listeners
_routeItemList[i].InvokeHandler(args);
if( TraceRoutedEvent.IsEnabled )
{
TraceRoutedEvent.Trace(
TraceEventType.Stop,
TraceRoutedEvent.InvokeHandlers,
_routeItemList[i].Target,
args,
args.Handled );
}
}
endTargetIndex = startTargetIndex;
}
}
}
///
/// Pushes the given node at the top of the stack of branches.
///
///
/// If a node in the tree has different visual and logical,
/// FrameworkElement will store the node on this stack of
/// branches. If the route ever returns to the same logical
/// tree, the event source will be restored.
///
/// NOTE: This method needs to be public because it is used
/// by FrameworkElement.
///
///
/// The node where the visual parent is different from the logical
/// parent.
///
///
/// The source that is currently being used, and which should be
/// restored when this branch is popped off the stack.
///
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Advanced)]
public void PushBranchNode(object node, object source)
{
BranchNode branchNode = new BranchNode();
branchNode.Node = node;
branchNode.Source = source;
BranchNodeStack.Push(branchNode);
}
///
/// Pops the given node from the top of the stack of branches.
///
///
/// If a node in the tree has different visual and logical,
/// FrameworkElement will store the node on this stack of
/// branches. If the route ever returns to the same logical
/// tree, the event source will be restored.
///
/// NOTE: This method needs to be public because it is used
/// by FrameworkElement.
///
///
/// The node where the visual parent was different from the
/// logical parent.
///
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Advanced)]
public object PopBranchNode()
{
if (BranchNodeStack.Count == 0)
return null;
BranchNode branchNode = BranchNodeStack.Pop();
return branchNode.Node;
}
///
/// Peeks the given node from the top of the stack of branches.
///
///
/// If a node in the tree has different visual and logical,
/// FrameworkElement will store the node on this stack of
/// branches. If the route ever returns to the same logical
/// tree, the event source will be restored.
///
/// NOTE: This method needs to be public because it is used
/// by FrameworkElement.
///
///
/// The node where the visual parent was different from the
/// logical parent.
///
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Advanced)]
public object PeekBranchNode()
{
if (BranchNodeStack.Count == 0)
return null;
BranchNode branchNode = BranchNodeStack.Peek();
return branchNode.Node;
}
///
/// Peeks the given source from the top of the stack of branches.
///
///
/// If a node in the tree has different visual and logical,
/// FrameworkElement will store the node on this stack of
/// branches. If the route ever returns to the same logical
/// tree, the event source will be restored.
///
/// NOTE: This method needs to be public because it is used
/// by FrameworkElement.
///
///
/// The source that was stored along with the node where the
/// visual parent was different from the logical parent.
///
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Advanced)]
public object PeekBranchSource()
{
if (BranchNodeStack.Count == 0)
return null;
BranchNode branchNode = BranchNodeStack.Peek();
return branchNode.Source;
}
#endregion External API
#region Operations
// Return associated RoutedEvent
internal RoutedEvent RoutedEvent
{
get {return _routedEvent;}
set { _routedEvent = value; }
}
// A BranchNode indicates a point in the tree where the logical and
// visual structure might diverge. When building a route, we store
// this branch node for every logical link we find. Along with the
// node where the possible divergence occurred, we store the source
// that the event should use. This is so that the source of an
// event will always be in the logical tree of the element handling
// the event.
private struct BranchNode
{
public object Node;
public object Source;
}
// Branch nodes are stored on a stack, which we create on-demand.
private Stack BranchNodeStack
{
get
{
if (_branchNodeStack == null)
{
_branchNodeStack = new Stack(1);
}
return _branchNodeStack;
}
}
// Add the given source to the source item list
// indicating what the source will be this point
// onwards in the route
internal void AddSource(object source)
{
int startIndex = _routeItemList.Count;
_sourceItemList.Add(new SourceItem(startIndex, source));
}
// Determine what the RoutedEventArgs.Source should be, at this
// point in the bubble. Also the endIndex output parameter tells
// you the exact index of the handlersList at which this source
// change ceases to apply
private object GetBubbleSource(int index, out int endIndex)
{
// If the Source never changes during the route execution,
// then we're done (just return null).
if (_sourceItemList.Count == 0)
{
endIndex = _routeItemList.Count;
return null;
}
// Similarly, if we're not to the point of the route of the first Source
// change, simply return null.
if (index < _sourceItemList[0].StartIndex)
{
endIndex = _sourceItemList[0].StartIndex;
return null;
}
// See if we should be using one of the intermediate
// sources
for (int i=0; i<_sourceItemList.Count -1; i++)
{
if (index >= _sourceItemList[i].StartIndex &&
index < _sourceItemList[i+1].StartIndex)
{
endIndex = _sourceItemList[i+1].StartIndex;
return _sourceItemList[i].Source;
}
}
// If we get here, we're on the last one,
// so return that.
endIndex = _routeItemList.Count;
return _sourceItemList[_sourceItemList.Count -1].Source;
}
// Determine what the RoutedEventArgs.Source should be, at this
// point in the tunnel. Also the startIndex output parameter tells
// you the exact index of the handlersList at which this source
// change starts to apply
private object GetTunnelSource(int index, out int startIndex)
{
// If the Source never changes during the route execution,
// then we're done (just return null).
if (_sourceItemList.Count == 0)
{
startIndex = 0;
return null;
}
// Similarly, if we're past the point of the route of the first Source
// change, simply return null.
if (index < _sourceItemList[0].StartIndex)
{
startIndex = 0;
return null;
}
// See if we should be using one of the intermediate
// sources
for (int i=0; i<_sourceItemList.Count -1; i++)
{
if (index >= _sourceItemList[i].StartIndex &&
index < _sourceItemList[i+1].StartIndex)
{
startIndex = _sourceItemList[i].StartIndex;
return _sourceItemList[i].Source;
}
}
// If we get here, we're on the last one, so return that.
startIndex = _sourceItemList[_sourceItemList.Count -1].StartIndex;
return _sourceItemList[_sourceItemList.Count -1].Source;
}
///
/// Cleanup all the references within the data
///
internal void Clear()
{
_routedEvent = null;
_routeItemList.Clear();
if (_branchNodeStack != null)
{
_branchNodeStack.Clear();
}
_sourceItemList.Clear();
}
#endregion Operations
#region Data
private RoutedEvent _routedEvent;
// Stores the routed event handlers to be
// invoked for the associated RoutedEvent
private FrugalStructList _routeItemList;
// Stores the branching nodes in the route
// that need to be backtracked while
// augmenting the route
private Stack _branchNodeStack;
// Stores Source Items for separated trees
private FrugalStructList _sourceItemList;
#endregion Data
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- FontStretches.cs
- StringUtil.cs
- MergeFilterQuery.cs
- ProcessHostMapPath.cs
- BidOverLoads.cs
- TextEditor.cs
- ControlBuilderAttribute.cs
- SecurityDocument.cs
- WindowInteractionStateTracker.cs
- SqlCommand.cs
- HtmlLabelAdapter.cs
- StylusDownEventArgs.cs
- CompatibleComparer.cs
- MouseGestureConverter.cs
- SystemIPGlobalProperties.cs
- ParserContext.cs
- SigningCredentials.cs
- GridLengthConverter.cs
- CompressionTransform.cs
- HtmlShimManager.cs
- DynamicDataRoute.cs
- SafeNativeMethodsOther.cs
- SamlSecurityTokenAuthenticator.cs
- SerialStream.cs
- CodeTypeMember.cs
- ServerTooBusyException.cs
- SingleAnimation.cs
- InfoCardCryptoHelper.cs
- UrlPath.cs
- TripleDESCryptoServiceProvider.cs
- SoapFault.cs
- TableChangeProcessor.cs
- ServiceBusyException.cs
- BitmapVisualManager.cs
- ExtensionQuery.cs
- Bits.cs
- IMembershipProvider.cs
- ListViewItem.cs
- GeometryHitTestResult.cs
- EventItfInfo.cs
- SessionState.cs
- RequestBringIntoViewEventArgs.cs
- IItemContainerGenerator.cs
- DataGridViewSortCompareEventArgs.cs
- ColorConvertedBitmap.cs
- CodeDomDecompiler.cs
- DataSourceXmlElementAttribute.cs
- InstanceDataCollection.cs
- ValidatorCompatibilityHelper.cs
- QilExpression.cs
- DynamicResourceExtensionConverter.cs
- WorkflowViewElement.cs
- PartialTrustVisibleAssembly.cs
- DataRowComparer.cs
- ILGenerator.cs
- SqlDataAdapter.cs
- FontUnitConverter.cs
- Win32Native.cs
- QilXmlReader.cs
- NativeMethods.cs
- AuthenticationSection.cs
- CustomErrorCollection.cs
- Normalization.cs
- _ShellExpression.cs
- MultilineStringConverter.cs
- DrawingContextDrawingContextWalker.cs
- ToolStripItemTextRenderEventArgs.cs
- JoinElimination.cs
- CollectionViewSource.cs
- SetIndexBinder.cs
- SqlConnectionHelper.cs
- SortQuery.cs
- ChainOfDependencies.cs
- RoleManagerSection.cs
- DrawingVisual.cs
- UnknownWrapper.cs
- InterleavedZipPartStream.cs
- ConfigPathUtility.cs
- WebReferenceOptions.cs
- StreamedWorkflowDefinitionContext.cs
- DataBoundLiteralControl.cs
- FormsAuthenticationUserCollection.cs
- AnnotationObservableCollection.cs
- HostElement.cs
- Comparer.cs
- Button.cs
- Command.cs
- ContextProperty.cs
- _SSPISessionCache.cs
- TemplatePagerField.cs
- DigestComparer.cs
- COM2ExtendedBrowsingHandler.cs
- PrinterSettings.cs
- NullableConverter.cs
- AVElementHelper.cs
- ListBoxDesigner.cs
- ToolStripItem.cs
- UIPermission.cs
- SecurityProtocol.cs
- WebOperationContext.cs