Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / ndp / fx / src / xsp / System / Web / UI / WebControls / SiteMapDataSource.cs / 1 / SiteMapDataSource.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Web.UI.WebControls { using System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.Drawing.Design; using System.Security.Permissions; using System.Web; using System.Web.UI; using System.Web.Util; [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] [ Designer("System.Web.UI.Design.WebControls.SiteMapDataSourceDesigner, " + AssemblyRef.SystemDesign), ParseChildren(true), PersistChildren(false), ToolboxBitmap(typeof(SiteMapDataSource)), WebSysDescription(SR.SiteMapDataSource_Description), WebSysDisplayName(SR.SiteMapDataSource_DisplayName) ] public class SiteMapDataSource : HierarchicalDataSourceControl, IDataSource, IListSource { private const string DefaultViewName = "DefaultView"; private ICollection _viewNames; private SiteMapDataSourceView _dataSourceView; private SiteMapProvider _provider; [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), WebSysDescription(SR.SiteMapDataSource_ContainsListCollection) ] public virtual bool ContainsListCollection { get { return ListSourceHelper.ContainsListCollection(this); } } ////// [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), WebSysDescription(SR.SiteMapDataSource_Provider) ] public SiteMapProvider Provider { get { if (_provider != null) return _provider; // If not specified, use the default provider. if (String.IsNullOrEmpty(SiteMapProvider)) { _provider = SiteMap.Provider; if (_provider == null) { throw new HttpException(SR.GetString(SR.SiteMapDataSource_DefaultProviderNotFound)); } } else { _provider = SiteMap.Providers[SiteMapProvider]; if (_provider == null) { throw new HttpException(SR.GetString(SR.SiteMapDataSource_ProviderNotFound, SiteMapProvider)); } } return _provider; } set { if (_provider != value) { _provider = value; OnDataSourceChanged(EventArgs.Empty); } } } ////// /// [ DefaultValue(true), WebCategory("Behavior"), WebSysDescription(SR.SiteMapDataSource_ShowStartingNode) ] public virtual bool ShowStartingNode { get { object o = ViewState["ShowStartingNode"]; return (o == null) ? true : (bool)o; } set { if (value != ShowStartingNode) { ViewState["ShowStartingNode"] = value; OnDataSourceChanged(EventArgs.Empty); } } } ///Indicates whether the starting node should be displayed. ////// [ DefaultValue(""), WebCategory("Behavior"), WebSysDescription(SR.SiteMapDataSource_SiteMapProvider) ] public virtual string SiteMapProvider { get { string provider = ViewState["SiteMapProvider"] as string; return (provider == null) ? String.Empty : provider; } set { if (value != SiteMapProvider) { _provider = null; ViewState["SiteMapProvider"] = value; OnDataSourceChanged(EventArgs.Empty); } } } ///Indicates the name of the SiteMapProvider used to populate the datasource control. ////// [ DefaultValue(0), WebCategory("Behavior"), WebSysDescription(SR.SiteMapDataSource_StartingNodeOffset) ] public virtual int StartingNodeOffset { get{ object o = ViewState["StartingNodeOffset"]; if (o == null) { return 0; } return (int)o; } set { if (value != StartingNodeOffset) { ViewState["StartingNodeOffset"] = value; OnDataSourceChanged(EventArgs.Empty); } } } ///Indicates the starting node offset used to populate the datasource control. ////// [ DefaultValue(false), WebCategory("Behavior"), WebSysDescription(SR.SiteMapDataSource_StartFromCurrentNode) ] public virtual bool StartFromCurrentNode { get { object o = ViewState["StartFromCurrentNode "]; return (o == null) ? false : (bool)o; } set { if (value != StartFromCurrentNode) { ViewState["StartFromCurrentNode "] = value; OnDataSourceChanged(EventArgs.Empty); } } } ////// /// [ DefaultValue(""), Editor("System.Web.UI.Design.UrlEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)), UrlProperty(), WebCategory("Behavior"), WebSysDescription(SR.SiteMapDataSource_StartingNodeUrl) ] public virtual string StartingNodeUrl { get { string startingNodeUrl = ViewState["StartingNodeUrl"] as string; return (startingNodeUrl == null) ? String.Empty : startingNodeUrl; } set { if (value != StartingNodeUrl) { ViewState["StartingNodeUrl"] = value; OnDataSourceChanged(EventArgs.Empty); } } } // Helper method to return the nodes. private SiteMapNodeCollection GetNodes() { SiteMapNode node = null; int startingNodeOffset = StartingNodeOffset; if (!String.IsNullOrEmpty(StartingNodeUrl) && StartFromCurrentNode) { throw new InvalidOperationException(SR.GetString(SR.SiteMapDataSource_StartingNodeUrlAndStartFromcurrentNode_Defined)); } if (StartFromCurrentNode) { node = Provider.CurrentNode; } else if (!String.IsNullOrEmpty(StartingNodeUrl)) { node = Provider.FindSiteMapNode(MakeUrlAbsolute(StartingNodeUrl)); if (node == null) { throw new ArgumentException(SR.GetString(SR.SiteMapPath_CannotFindUrl, StartingNodeUrl)); } } else { node = Provider.RootNode; } if (node == null) { return null; } if (startingNodeOffset <= 0) { if (startingNodeOffset != 0) { // Hind neighborhood nodes based on startingNodeOffset Provider.HintNeighborhoodNodes(node, Math.Abs(startingNodeOffset), 0); SiteMapNode parentNode = node.ParentNode; while (startingNodeOffset < 0 && parentNode != null) { node = node.ParentNode; parentNode = node.ParentNode; startingNodeOffset++; } } return GetNodes(node); } // else if (startingNodeOffset > 0) SiteMapNode currentNode = Provider.GetCurrentNodeAndHintAncestorNodes(-1); // If the current node is not in StartingNode's subtree, return null. if (currentNode == null || !currentNode.IsDescendantOf(node) || currentNode.Equals(node)) { return null; } SiteMapNode leadingNode = currentNode; // Create a gap of n levels between the following and the leading nodes. for (int i = 0; i < startingNodeOffset; i++) { leadingNode = leadingNode.ParentNode; // If the current node is within n levels below the starting node, // use the current node. if (leadingNode == null || leadingNode.Equals(node)) { return GetNodes(currentNode); } } SiteMapNode followingNode = currentNode; while (leadingNode != null && !leadingNode.Equals(node)) { followingNode = followingNode.ParentNode; leadingNode = leadingNode.ParentNode; } return GetNodes(followingNode); } private SiteMapNodeCollection GetNodes(SiteMapNode node) { if (ShowStartingNode) { return new SiteMapNodeCollection(node); } return node.ChildNodes; } protected override HierarchicalDataSourceView GetHierarchicalView(string viewPath) { if (Provider == null) throw new HttpException(SR.GetString(SR.SiteMapDataSource_ProviderNotFound, SiteMapProvider)); return GetTreeView(viewPath); } public virtual IList GetList() { return ListSourceHelper.GetList(this); } // Helper method to get the non-hierarhical path view. ie. from BaseNode to currentNode. // if currentNode is not in the subtree rooted at basenode, returns empty collection. internal SiteMapNodeCollection GetPathNodeCollection(string viewPath) { SiteMapNodeCollection collection = null; if (String.IsNullOrEmpty(viewPath)) { collection = GetNodes(); } else { // Otherwise, return the child nodes specified by the key (viewPath) SiteMapNode node = Provider.FindSiteMapNodeFromKey(viewPath); if (node != null) { collection = node.ChildNodes; } } if (collection == null) { collection = SiteMapNodeCollection.Empty; } return collection; } private HierarchicalDataSourceView GetTreeView(string viewPath) { SiteMapNode node = null; // When querying for the whole view, returns the view starting from the designated node. if (String.IsNullOrEmpty(viewPath)) { SiteMapNodeCollection nodes = GetNodes(); if (nodes != null) { return nodes.GetHierarchicalDataSourceView(); } } // Otherwise, return the child nodes specified by the key (viewPath) else { node = Provider.FindSiteMapNodeFromKey(viewPath); if (node != null) return node.ChildNodes.GetHierarchicalDataSourceView(); } // return the view of an empty readonly collection return SiteMapNodeCollection.Empty.GetHierarchicalDataSourceView(); } public virtual DataSourceView GetView(string viewName) { if (Provider == null) throw new HttpException(SR.GetString(SR.SiteMapDataSource_ProviderNotFound, SiteMapProvider)); if (_dataSourceView == null) { _dataSourceView = SiteMapNodeCollection.ReadOnly(GetPathNodeCollection(viewName)).GetDataSourceView(this, String.Empty); } return _dataSourceView; } public virtual ICollection GetViewNames() { if (_viewNames == null) { _viewNames = new string[1] { DefaultViewName }; } return _viewNames; } private string MakeUrlAbsolute(string url) { // check if its empty or already absolute if (url.Length == 0 || !UrlPath.IsRelativeUrl(url)) { return url; } string baseUrl = AppRelativeTemplateSourceDirectory; if (baseUrl.Length == 0) { return url; } // Make it absolute return UrlPath.Combine(baseUrl, url); } #region IDataSource implementations ///Indicates the starting node url used to populate the datasource control. ////// Raised when the underlying data source has changed. The /// change may be due to a change in the control's properties, /// or a change in the data due to an edit action performed by /// the DataSourceControl. /// event EventHandler IDataSource.DataSourceChanged { add { ((IHierarchicalDataSource)this).DataSourceChanged += value; } remove { ((IHierarchicalDataSource)this).DataSourceChanged -= value; } } ///DataSourceView IDataSource.GetView(string viewName) { return GetView(viewName); } /// ICollection IDataSource.GetViewNames() { return GetViewNames(); } #endregion #region Implementation of IListSource /// bool IListSource.ContainsListCollection { get { if (DesignMode) { return false; } return ContainsListCollection; } } /// IList IListSource.GetList() { if (DesignMode) { return null; } return GetList(); } #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Web.UI.WebControls { using System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.Drawing.Design; using System.Security.Permissions; using System.Web; using System.Web.UI; using System.Web.Util; [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] [ Designer("System.Web.UI.Design.WebControls.SiteMapDataSourceDesigner, " + AssemblyRef.SystemDesign), ParseChildren(true), PersistChildren(false), ToolboxBitmap(typeof(SiteMapDataSource)), WebSysDescription(SR.SiteMapDataSource_Description), WebSysDisplayName(SR.SiteMapDataSource_DisplayName) ] public class SiteMapDataSource : HierarchicalDataSourceControl, IDataSource, IListSource { private const string DefaultViewName = "DefaultView"; private ICollection _viewNames; private SiteMapDataSourceView _dataSourceView; private SiteMapProvider _provider; [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), WebSysDescription(SR.SiteMapDataSource_ContainsListCollection) ] public virtual bool ContainsListCollection { get { return ListSourceHelper.ContainsListCollection(this); } } ////// [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), WebSysDescription(SR.SiteMapDataSource_Provider) ] public SiteMapProvider Provider { get { if (_provider != null) return _provider; // If not specified, use the default provider. if (String.IsNullOrEmpty(SiteMapProvider)) { _provider = SiteMap.Provider; if (_provider == null) { throw new HttpException(SR.GetString(SR.SiteMapDataSource_DefaultProviderNotFound)); } } else { _provider = SiteMap.Providers[SiteMapProvider]; if (_provider == null) { throw new HttpException(SR.GetString(SR.SiteMapDataSource_ProviderNotFound, SiteMapProvider)); } } return _provider; } set { if (_provider != value) { _provider = value; OnDataSourceChanged(EventArgs.Empty); } } } ////// /// [ DefaultValue(true), WebCategory("Behavior"), WebSysDescription(SR.SiteMapDataSource_ShowStartingNode) ] public virtual bool ShowStartingNode { get { object o = ViewState["ShowStartingNode"]; return (o == null) ? true : (bool)o; } set { if (value != ShowStartingNode) { ViewState["ShowStartingNode"] = value; OnDataSourceChanged(EventArgs.Empty); } } } ///Indicates whether the starting node should be displayed. ////// [ DefaultValue(""), WebCategory("Behavior"), WebSysDescription(SR.SiteMapDataSource_SiteMapProvider) ] public virtual string SiteMapProvider { get { string provider = ViewState["SiteMapProvider"] as string; return (provider == null) ? String.Empty : provider; } set { if (value != SiteMapProvider) { _provider = null; ViewState["SiteMapProvider"] = value; OnDataSourceChanged(EventArgs.Empty); } } } ///Indicates the name of the SiteMapProvider used to populate the datasource control. ////// [ DefaultValue(0), WebCategory("Behavior"), WebSysDescription(SR.SiteMapDataSource_StartingNodeOffset) ] public virtual int StartingNodeOffset { get{ object o = ViewState["StartingNodeOffset"]; if (o == null) { return 0; } return (int)o; } set { if (value != StartingNodeOffset) { ViewState["StartingNodeOffset"] = value; OnDataSourceChanged(EventArgs.Empty); } } } ///Indicates the starting node offset used to populate the datasource control. ////// [ DefaultValue(false), WebCategory("Behavior"), WebSysDescription(SR.SiteMapDataSource_StartFromCurrentNode) ] public virtual bool StartFromCurrentNode { get { object o = ViewState["StartFromCurrentNode "]; return (o == null) ? false : (bool)o; } set { if (value != StartFromCurrentNode) { ViewState["StartFromCurrentNode "] = value; OnDataSourceChanged(EventArgs.Empty); } } } ////// /// [ DefaultValue(""), Editor("System.Web.UI.Design.UrlEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)), UrlProperty(), WebCategory("Behavior"), WebSysDescription(SR.SiteMapDataSource_StartingNodeUrl) ] public virtual string StartingNodeUrl { get { string startingNodeUrl = ViewState["StartingNodeUrl"] as string; return (startingNodeUrl == null) ? String.Empty : startingNodeUrl; } set { if (value != StartingNodeUrl) { ViewState["StartingNodeUrl"] = value; OnDataSourceChanged(EventArgs.Empty); } } } // Helper method to return the nodes. private SiteMapNodeCollection GetNodes() { SiteMapNode node = null; int startingNodeOffset = StartingNodeOffset; if (!String.IsNullOrEmpty(StartingNodeUrl) && StartFromCurrentNode) { throw new InvalidOperationException(SR.GetString(SR.SiteMapDataSource_StartingNodeUrlAndStartFromcurrentNode_Defined)); } if (StartFromCurrentNode) { node = Provider.CurrentNode; } else if (!String.IsNullOrEmpty(StartingNodeUrl)) { node = Provider.FindSiteMapNode(MakeUrlAbsolute(StartingNodeUrl)); if (node == null) { throw new ArgumentException(SR.GetString(SR.SiteMapPath_CannotFindUrl, StartingNodeUrl)); } } else { node = Provider.RootNode; } if (node == null) { return null; } if (startingNodeOffset <= 0) { if (startingNodeOffset != 0) { // Hind neighborhood nodes based on startingNodeOffset Provider.HintNeighborhoodNodes(node, Math.Abs(startingNodeOffset), 0); SiteMapNode parentNode = node.ParentNode; while (startingNodeOffset < 0 && parentNode != null) { node = node.ParentNode; parentNode = node.ParentNode; startingNodeOffset++; } } return GetNodes(node); } // else if (startingNodeOffset > 0) SiteMapNode currentNode = Provider.GetCurrentNodeAndHintAncestorNodes(-1); // If the current node is not in StartingNode's subtree, return null. if (currentNode == null || !currentNode.IsDescendantOf(node) || currentNode.Equals(node)) { return null; } SiteMapNode leadingNode = currentNode; // Create a gap of n levels between the following and the leading nodes. for (int i = 0; i < startingNodeOffset; i++) { leadingNode = leadingNode.ParentNode; // If the current node is within n levels below the starting node, // use the current node. if (leadingNode == null || leadingNode.Equals(node)) { return GetNodes(currentNode); } } SiteMapNode followingNode = currentNode; while (leadingNode != null && !leadingNode.Equals(node)) { followingNode = followingNode.ParentNode; leadingNode = leadingNode.ParentNode; } return GetNodes(followingNode); } private SiteMapNodeCollection GetNodes(SiteMapNode node) { if (ShowStartingNode) { return new SiteMapNodeCollection(node); } return node.ChildNodes; } protected override HierarchicalDataSourceView GetHierarchicalView(string viewPath) { if (Provider == null) throw new HttpException(SR.GetString(SR.SiteMapDataSource_ProviderNotFound, SiteMapProvider)); return GetTreeView(viewPath); } public virtual IList GetList() { return ListSourceHelper.GetList(this); } // Helper method to get the non-hierarhical path view. ie. from BaseNode to currentNode. // if currentNode is not in the subtree rooted at basenode, returns empty collection. internal SiteMapNodeCollection GetPathNodeCollection(string viewPath) { SiteMapNodeCollection collection = null; if (String.IsNullOrEmpty(viewPath)) { collection = GetNodes(); } else { // Otherwise, return the child nodes specified by the key (viewPath) SiteMapNode node = Provider.FindSiteMapNodeFromKey(viewPath); if (node != null) { collection = node.ChildNodes; } } if (collection == null) { collection = SiteMapNodeCollection.Empty; } return collection; } private HierarchicalDataSourceView GetTreeView(string viewPath) { SiteMapNode node = null; // When querying for the whole view, returns the view starting from the designated node. if (String.IsNullOrEmpty(viewPath)) { SiteMapNodeCollection nodes = GetNodes(); if (nodes != null) { return nodes.GetHierarchicalDataSourceView(); } } // Otherwise, return the child nodes specified by the key (viewPath) else { node = Provider.FindSiteMapNodeFromKey(viewPath); if (node != null) return node.ChildNodes.GetHierarchicalDataSourceView(); } // return the view of an empty readonly collection return SiteMapNodeCollection.Empty.GetHierarchicalDataSourceView(); } public virtual DataSourceView GetView(string viewName) { if (Provider == null) throw new HttpException(SR.GetString(SR.SiteMapDataSource_ProviderNotFound, SiteMapProvider)); if (_dataSourceView == null) { _dataSourceView = SiteMapNodeCollection.ReadOnly(GetPathNodeCollection(viewName)).GetDataSourceView(this, String.Empty); } return _dataSourceView; } public virtual ICollection GetViewNames() { if (_viewNames == null) { _viewNames = new string[1] { DefaultViewName }; } return _viewNames; } private string MakeUrlAbsolute(string url) { // check if its empty or already absolute if (url.Length == 0 || !UrlPath.IsRelativeUrl(url)) { return url; } string baseUrl = AppRelativeTemplateSourceDirectory; if (baseUrl.Length == 0) { return url; } // Make it absolute return UrlPath.Combine(baseUrl, url); } #region IDataSource implementations ///Indicates the starting node url used to populate the datasource control. ////// Raised when the underlying data source has changed. The /// change may be due to a change in the control's properties, /// or a change in the data due to an edit action performed by /// the DataSourceControl. /// event EventHandler IDataSource.DataSourceChanged { add { ((IHierarchicalDataSource)this).DataSourceChanged += value; } remove { ((IHierarchicalDataSource)this).DataSourceChanged -= value; } } ///DataSourceView IDataSource.GetView(string viewName) { return GetView(viewName); } /// ICollection IDataSource.GetViewNames() { return GetViewNames(); } #endregion #region Implementation of IListSource /// bool IListSource.ContainsListCollection { get { if (DesignMode) { return false; } return ContainsListCollection; } } /// IList IListSource.GetList() { if (DesignMode) { return null; } return GetList(); } #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- WebScriptEndpoint.cs
- FreezableOperations.cs
- AdRotatorDesigner.cs
- GridViewSortEventArgs.cs
- TypeGeneratedEventArgs.cs
- FontEmbeddingManager.cs
- ProtocolReflector.cs
- Decorator.cs
- NavigationWindow.cs
- Variable.cs
- VisualStyleRenderer.cs
- DataTableClearEvent.cs
- KerberosSecurityTokenProvider.cs
- RegistryKey.cs
- PropertySegmentSerializationProvider.cs
- SequenceDesigner.cs
- ellipse.cs
- XmlWriterTraceListener.cs
- AlphaSortedEnumConverter.cs
- MarkupWriter.cs
- TextChangedEventArgs.cs
- DependencyObject.cs
- ReadOnlyAttribute.cs
- CustomError.cs
- PropertyToken.cs
- SqlMethodAttribute.cs
- TreeNodeBindingCollection.cs
- WebBrowserNavigatingEventHandler.cs
- MimeBasePart.cs
- IsolatedStorage.cs
- BitmapEffectDrawingContextState.cs
- AssemblyResourceLoader.cs
- TabItemWrapperAutomationPeer.cs
- ObjectDataProvider.cs
- DesignerValidatorAdapter.cs
- ConnectionOrientedTransportBindingElement.cs
- DigitalSignature.cs
- ProviderConnectionPointCollection.cs
- AuthStoreRoleProvider.cs
- StorageComplexPropertyMapping.cs
- BasicExpandProvider.cs
- PersistenceTypeAttribute.cs
- dataprotectionpermission.cs
- SystemSounds.cs
- LinkedList.cs
- GeneralTransform.cs
- RepeatButton.cs
- ZipIOLocalFileHeader.cs
- PixelFormat.cs
- RSAPKCS1SignatureDeformatter.cs
- _ReceiveMessageOverlappedAsyncResult.cs
- listitem.cs
- ProfilePropertySettingsCollection.cs
- ComContractElement.cs
- RSAPKCS1SignatureDeformatter.cs
- PreDigestedSignedInfo.cs
- _SecureChannel.cs
- TemplateBindingExpressionConverter.cs
- _SSPISessionCache.cs
- CompareInfo.cs
- ServiceSecurityAuditElement.cs
- SystemWebSectionGroup.cs
- SimpleBitVector32.cs
- SvcMapFileSerializer.cs
- MediaContext.cs
- WebServiceParameterData.cs
- Quaternion.cs
- BinaryCommonClasses.cs
- EncoderReplacementFallback.cs
- TimeSpanOrInfiniteValidator.cs
- XmlNotation.cs
- TextCompositionEventArgs.cs
- SqlClientWrapperSmiStreamChars.cs
- SqlClientWrapperSmiStream.cs
- StaticTextPointer.cs
- FormViewDeletedEventArgs.cs
- RegexCapture.cs
- ResourcesBuildProvider.cs
- SelectedPathEditor.cs
- Vector3DAnimationUsingKeyFrames.cs
- PolicyValidationException.cs
- AccessDataSourceView.cs
- ConfigurationPropertyAttribute.cs
- GeneralTransform3DTo2DTo3D.cs
- TraceHelpers.cs
- RoutedEventConverter.cs
- AddInToken.cs
- MouseGestureValueSerializer.cs
- ReachPageContentCollectionSerializerAsync.cs
- CollectionAdapters.cs
- bidPrivateBase.cs
- CodeStatementCollection.cs
- CipherData.cs
- Geometry.cs
- SqlCacheDependencySection.cs
- XamlSerializationHelper.cs
- ConfigurationSchemaErrors.cs
- EncoderParameter.cs
- ListViewSelectEventArgs.cs
- TextRange.cs