Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / xsp / System / DynamicData / DynamicData / FieldTemplateFactory.cs / 1305376 / FieldTemplateFactory.cs
using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Diagnostics; using System.Globalization; using System.Security.Permissions; using System.Web.Compilation; using System.Web.Hosting; using System.Web.UI.WebControls; namespace System.Web.DynamicData { ////// Default implementation of IFieldTemplateFactory. It uses user controls for the field templates. /// public class FieldTemplateFactory : IFieldTemplateFactory { private const string IntegerField = "Integer"; private const string ForeignKeyField = "ForeignKey"; private const string ChildrenField = "Children"; private const string ManyToManyField = "ManyToMany"; private const string EnumerationField = "Enumeration"; private const string EditModePathModifier = "_Edit"; private const string InsertModePathModifier = "_Insert"; private Dictionary_typesToTemplateNames; private Dictionary _typesFallBacks; private TemplateFactory _templateFactory; /// /// public FieldTemplateFactory() { InitTypesToTemplateNamesTable(); BuildTypeFallbackTable(); _templateFactory = new TemplateFactory("FieldTemplates"); } // For unit test purpose internal FieldTemplateFactory(VirtualPathProvider vpp) : this() { _templateFactory.VirtualPathProvider = vpp; } ////// Sets the folder containing the user controls. By default, this is ~/DynamicData/FieldTemplates/ /// public string TemplateFolderVirtualPath { get { return _templateFactory.TemplateFolderVirtualPath; } set { _templateFactory.TemplateFolderVirtualPath = value; } } ////// The MetaModel that the factory is associated with /// public MetaModel Model { get { return _templateFactory.Model; } private set { _templateFactory.Model = value; } } private void InitTypesToTemplateNamesTable() { _typesToTemplateNames = new Dictionary(); _typesToTemplateNames[typeof(int)] = FieldTemplateFactory.IntegerField; _typesToTemplateNames[typeof(string)] = DataType.Text.ToString(); } private void BuildTypeFallbackTable() { _typesFallBacks = new Dictionary (); _typesFallBacks[typeof(float)] = typeof(decimal); _typesFallBacks[typeof(double)] = typeof(decimal); _typesFallBacks[typeof(Int16)] = typeof(int); _typesFallBacks[typeof(byte)] = typeof(int); _typesFallBacks[typeof(long)] = typeof(int); // Fall back to strings for most types _typesFallBacks[typeof(char)] = typeof(string); _typesFallBacks[typeof(int)] = typeof(string); _typesFallBacks[typeof(decimal)] = typeof(string); _typesFallBacks[typeof(Guid)] = typeof(string); _typesFallBacks[typeof(DateTime)] = typeof(string); _typesFallBacks[typeof(DateTimeOffset)] = typeof(string); _typesFallBacks[typeof(TimeSpan)] = typeof(string); // } private Type GetFallBackType(Type t) { // Check if there is a fallback type Type fallbackType; if (_typesFallBacks.TryGetValue(t, out fallbackType)) return fallbackType; return null; } // Internal for unit test purpose internal string GetFieldTemplateVirtualPathWithCaching(MetaColumn column, DataBoundControlMode mode, string uiHint) { // Compute a cache key based on all the input paramaters long cacheKey = Misc.CombineHashCodes(uiHint, column, mode); Func templatePathFactoryFunction = () => GetFieldTemplateVirtualPath(column, mode, uiHint); return _templateFactory.GetTemplatePath(cacheKey, templatePathFactoryFunction); } /// /// Returns the virtual path of the field template user control to be used, based on various pieces of data /// /// The MetaColumn for which the field template is needed /// The mode (Readonly, Edit, Insert) for which the field template is needed /// The UIHint (if any) that should affect the field template lookup ///public virtual string GetFieldTemplateVirtualPath(MetaColumn column, DataBoundControlMode mode, string uiHint) { mode = PreprocessMode(column, mode); bool hasDataTypeAttribute = column != null && column.DataTypeAttribute != null; // Set the UIHint in some special cases, but don't do it if we already have one or // if we have a DataTypeAttribute if (String.IsNullOrEmpty(uiHint) && !hasDataTypeAttribute) { // Check if it's an association // Or if it is an enum if (column is MetaForeignKeyColumn) { uiHint = FieldTemplateFactory.ForeignKeyField; } else if (column is MetaChildrenColumn) { var childrenColumn = (MetaChildrenColumn)column; if (childrenColumn.IsManyToMany) { uiHint = FieldTemplateFactory.ManyToManyField; } else { uiHint = FieldTemplateFactory.ChildrenField; } } else if (column.ColumnType.IsEnum) { uiHint = FieldTemplateFactory.EnumerationField; } } return GetVirtualPathWithModeFallback(uiHint, column, mode); } /// /// Gets a chance to change the mode. e.g. an Edit mode request can be turned into ReadOnly mode /// if the column is a primary key /// public virtual DataBoundControlMode PreprocessMode(MetaColumn column, DataBoundControlMode mode) { if (column == null) { throw new ArgumentNullException("column"); } // Primary keys can't be edited, so put them in readonly mode. Note that this // does not apply to Insert mode, which is fine if (column.IsPrimaryKey && mode == DataBoundControlMode.Edit) { mode = DataBoundControlMode.ReadOnly; } // Generated columns should never be editable/insertable if (column.IsGenerated) { mode = DataBoundControlMode.ReadOnly; } // ReadOnly columns cannot be edited nor inserted, and are always in Display mode if (column.IsReadOnly) { if (mode == DataBoundControlMode.Insert && column.AllowInitialValue) { // but don't change the mode if we're in insert and an initial value is allowed } else { mode = DataBoundControlMode.ReadOnly; } } // If initial value is not allowed set mode to ReadOnly if (mode == DataBoundControlMode.Insert && !column.AllowInitialValue) { mode = DataBoundControlMode.ReadOnly; } if (column is MetaForeignKeyColumn) { // If the foreign key is part of the primary key (e.g. Order and Product in Order_Details table), // change the mode to ReadOnly so that they can't be edited. if (mode == DataBoundControlMode.Edit && ((MetaForeignKeyColumn)column).IsPrimaryKeyInThisTable) { mode = DataBoundControlMode.ReadOnly; } } return mode; } private string GetVirtualPathWithModeFallback(string templateName, MetaColumn column, DataBoundControlMode mode) { // Try not only the requested mode, but others if needed. Basically: // - an edit template can default to an item template // - an insert template can default to an edit template, then to an item template for (var currentMode = mode; currentMode >= 0; currentMode--) { string virtualPath = GetVirtualPathForMode(templateName, column, currentMode); if (virtualPath != null) return virtualPath; } // We couldn't locate any field template at all, so give up return null; } private string GetVirtualPathForMode(string templateName, MetaColumn column, DataBoundControlMode mode) { // If we got a template name, try it if (!String.IsNullOrEmpty(templateName)) { string virtualPath = GetVirtualPathIfExists(templateName, column, mode); if (virtualPath != null) return virtualPath; } // Otherwise, use the column's type return GetVirtualPathForTypeWithFallback(column.ColumnType, column, mode); } private string GetVirtualPathForTypeWithFallback(Type fieldType, MetaColumn column, DataBoundControlMode mode) { string templateName; string virtualPath; // If we have a data type attribute if (column.DataTypeAttribute != null) { templateName = column.DataTypeAttribute.GetDataTypeName(); // Try to get the path from it virtualPath = GetVirtualPathIfExists(templateName, column, mode); if (virtualPath != null) return virtualPath; } // Try the actual fully qualified type name (i.e. with the namespace) virtualPath = GetVirtualPathIfExists(fieldType.FullName, column, mode); if (virtualPath != null) return virtualPath; // Try the simple type name virtualPath = GetVirtualPathIfExists(fieldType.Name, column, mode); if (virtualPath != null) return virtualPath; // If our type name table has an entry for it, try it if (_typesToTemplateNames.TryGetValue(fieldType, out templateName)) { virtualPath = GetVirtualPathIfExists(templateName, column, mode); if (virtualPath != null) return virtualPath; } // Check if there is a fallback type Type fallbackType = GetFallBackType(fieldType); // If not, we've run out of options if (fallbackType == null) return null; // If so, try it return GetVirtualPathForTypeWithFallback(fallbackType, column, mode); } private string GetVirtualPathIfExists(string templateName, MetaColumn column, DataBoundControlMode mode) { // Build the path string virtualPath = BuildVirtualPath(templateName, column, mode); // Check if it exists if (_templateFactory.FileExists(virtualPath)) return virtualPath; // If not, return null return null; } ////// Build the virtual path to the field template user control based on the template name and mode. /// By default, it returns names that look like TemplateName_ModeName.ascx, in the folder specified /// by TemplateFolderVirtualPath. /// /// /// /// ///public virtual string BuildVirtualPath(string templateName, MetaColumn column, DataBoundControlMode mode) { if (String.IsNullOrEmpty(templateName)) { throw new ArgumentNullException("templateName"); } string modePathModifier = null; switch (mode) { case DataBoundControlMode.ReadOnly: modePathModifier = String.Empty; break; case DataBoundControlMode.Edit: modePathModifier = FieldTemplateFactory.EditModePathModifier; break; case DataBoundControlMode.Insert: modePathModifier = FieldTemplateFactory.InsertModePathModifier; break; default: Debug.Assert(false); break; } return String.Format(CultureInfo.InvariantCulture, TemplateFolderVirtualPath + "{0}{1}.ascx", templateName, modePathModifier); } #region IFieldTemplateFactory Members public virtual void Initialize(MetaModel model) { Model = model; } /// /// See IFieldTemplateFactory for details. /// ///public virtual IFieldTemplate CreateFieldTemplate(MetaColumn column, DataBoundControlMode mode, string uiHint) { string fieldTemplatePath = GetFieldTemplateVirtualPathWithCaching(column, mode, uiHint); if (fieldTemplatePath == null) return null; return (IFieldTemplate)BuildManager.CreateInstanceFromVirtualPath( fieldTemplatePath, typeof(IFieldTemplate)); } #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Diagnostics; using System.Globalization; using System.Security.Permissions; using System.Web.Compilation; using System.Web.Hosting; using System.Web.UI.WebControls; namespace System.Web.DynamicData { /// /// Default implementation of IFieldTemplateFactory. It uses user controls for the field templates. /// public class FieldTemplateFactory : IFieldTemplateFactory { private const string IntegerField = "Integer"; private const string ForeignKeyField = "ForeignKey"; private const string ChildrenField = "Children"; private const string ManyToManyField = "ManyToMany"; private const string EnumerationField = "Enumeration"; private const string EditModePathModifier = "_Edit"; private const string InsertModePathModifier = "_Insert"; private Dictionary_typesToTemplateNames; private Dictionary _typesFallBacks; private TemplateFactory _templateFactory; /// /// public FieldTemplateFactory() { InitTypesToTemplateNamesTable(); BuildTypeFallbackTable(); _templateFactory = new TemplateFactory("FieldTemplates"); } // For unit test purpose internal FieldTemplateFactory(VirtualPathProvider vpp) : this() { _templateFactory.VirtualPathProvider = vpp; } ////// Sets the folder containing the user controls. By default, this is ~/DynamicData/FieldTemplates/ /// public string TemplateFolderVirtualPath { get { return _templateFactory.TemplateFolderVirtualPath; } set { _templateFactory.TemplateFolderVirtualPath = value; } } ////// The MetaModel that the factory is associated with /// public MetaModel Model { get { return _templateFactory.Model; } private set { _templateFactory.Model = value; } } private void InitTypesToTemplateNamesTable() { _typesToTemplateNames = new Dictionary(); _typesToTemplateNames[typeof(int)] = FieldTemplateFactory.IntegerField; _typesToTemplateNames[typeof(string)] = DataType.Text.ToString(); } private void BuildTypeFallbackTable() { _typesFallBacks = new Dictionary (); _typesFallBacks[typeof(float)] = typeof(decimal); _typesFallBacks[typeof(double)] = typeof(decimal); _typesFallBacks[typeof(Int16)] = typeof(int); _typesFallBacks[typeof(byte)] = typeof(int); _typesFallBacks[typeof(long)] = typeof(int); // Fall back to strings for most types _typesFallBacks[typeof(char)] = typeof(string); _typesFallBacks[typeof(int)] = typeof(string); _typesFallBacks[typeof(decimal)] = typeof(string); _typesFallBacks[typeof(Guid)] = typeof(string); _typesFallBacks[typeof(DateTime)] = typeof(string); _typesFallBacks[typeof(DateTimeOffset)] = typeof(string); _typesFallBacks[typeof(TimeSpan)] = typeof(string); // } private Type GetFallBackType(Type t) { // Check if there is a fallback type Type fallbackType; if (_typesFallBacks.TryGetValue(t, out fallbackType)) return fallbackType; return null; } // Internal for unit test purpose internal string GetFieldTemplateVirtualPathWithCaching(MetaColumn column, DataBoundControlMode mode, string uiHint) { // Compute a cache key based on all the input paramaters long cacheKey = Misc.CombineHashCodes(uiHint, column, mode); Func templatePathFactoryFunction = () => GetFieldTemplateVirtualPath(column, mode, uiHint); return _templateFactory.GetTemplatePath(cacheKey, templatePathFactoryFunction); } /// /// Returns the virtual path of the field template user control to be used, based on various pieces of data /// /// The MetaColumn for which the field template is needed /// The mode (Readonly, Edit, Insert) for which the field template is needed /// The UIHint (if any) that should affect the field template lookup ///public virtual string GetFieldTemplateVirtualPath(MetaColumn column, DataBoundControlMode mode, string uiHint) { mode = PreprocessMode(column, mode); bool hasDataTypeAttribute = column != null && column.DataTypeAttribute != null; // Set the UIHint in some special cases, but don't do it if we already have one or // if we have a DataTypeAttribute if (String.IsNullOrEmpty(uiHint) && !hasDataTypeAttribute) { // Check if it's an association // Or if it is an enum if (column is MetaForeignKeyColumn) { uiHint = FieldTemplateFactory.ForeignKeyField; } else if (column is MetaChildrenColumn) { var childrenColumn = (MetaChildrenColumn)column; if (childrenColumn.IsManyToMany) { uiHint = FieldTemplateFactory.ManyToManyField; } else { uiHint = FieldTemplateFactory.ChildrenField; } } else if (column.ColumnType.IsEnum) { uiHint = FieldTemplateFactory.EnumerationField; } } return GetVirtualPathWithModeFallback(uiHint, column, mode); } /// /// Gets a chance to change the mode. e.g. an Edit mode request can be turned into ReadOnly mode /// if the column is a primary key /// public virtual DataBoundControlMode PreprocessMode(MetaColumn column, DataBoundControlMode mode) { if (column == null) { throw new ArgumentNullException("column"); } // Primary keys can't be edited, so put them in readonly mode. Note that this // does not apply to Insert mode, which is fine if (column.IsPrimaryKey && mode == DataBoundControlMode.Edit) { mode = DataBoundControlMode.ReadOnly; } // Generated columns should never be editable/insertable if (column.IsGenerated) { mode = DataBoundControlMode.ReadOnly; } // ReadOnly columns cannot be edited nor inserted, and are always in Display mode if (column.IsReadOnly) { if (mode == DataBoundControlMode.Insert && column.AllowInitialValue) { // but don't change the mode if we're in insert and an initial value is allowed } else { mode = DataBoundControlMode.ReadOnly; } } // If initial value is not allowed set mode to ReadOnly if (mode == DataBoundControlMode.Insert && !column.AllowInitialValue) { mode = DataBoundControlMode.ReadOnly; } if (column is MetaForeignKeyColumn) { // If the foreign key is part of the primary key (e.g. Order and Product in Order_Details table), // change the mode to ReadOnly so that they can't be edited. if (mode == DataBoundControlMode.Edit && ((MetaForeignKeyColumn)column).IsPrimaryKeyInThisTable) { mode = DataBoundControlMode.ReadOnly; } } return mode; } private string GetVirtualPathWithModeFallback(string templateName, MetaColumn column, DataBoundControlMode mode) { // Try not only the requested mode, but others if needed. Basically: // - an edit template can default to an item template // - an insert template can default to an edit template, then to an item template for (var currentMode = mode; currentMode >= 0; currentMode--) { string virtualPath = GetVirtualPathForMode(templateName, column, currentMode); if (virtualPath != null) return virtualPath; } // We couldn't locate any field template at all, so give up return null; } private string GetVirtualPathForMode(string templateName, MetaColumn column, DataBoundControlMode mode) { // If we got a template name, try it if (!String.IsNullOrEmpty(templateName)) { string virtualPath = GetVirtualPathIfExists(templateName, column, mode); if (virtualPath != null) return virtualPath; } // Otherwise, use the column's type return GetVirtualPathForTypeWithFallback(column.ColumnType, column, mode); } private string GetVirtualPathForTypeWithFallback(Type fieldType, MetaColumn column, DataBoundControlMode mode) { string templateName; string virtualPath; // If we have a data type attribute if (column.DataTypeAttribute != null) { templateName = column.DataTypeAttribute.GetDataTypeName(); // Try to get the path from it virtualPath = GetVirtualPathIfExists(templateName, column, mode); if (virtualPath != null) return virtualPath; } // Try the actual fully qualified type name (i.e. with the namespace) virtualPath = GetVirtualPathIfExists(fieldType.FullName, column, mode); if (virtualPath != null) return virtualPath; // Try the simple type name virtualPath = GetVirtualPathIfExists(fieldType.Name, column, mode); if (virtualPath != null) return virtualPath; // If our type name table has an entry for it, try it if (_typesToTemplateNames.TryGetValue(fieldType, out templateName)) { virtualPath = GetVirtualPathIfExists(templateName, column, mode); if (virtualPath != null) return virtualPath; } // Check if there is a fallback type Type fallbackType = GetFallBackType(fieldType); // If not, we've run out of options if (fallbackType == null) return null; // If so, try it return GetVirtualPathForTypeWithFallback(fallbackType, column, mode); } private string GetVirtualPathIfExists(string templateName, MetaColumn column, DataBoundControlMode mode) { // Build the path string virtualPath = BuildVirtualPath(templateName, column, mode); // Check if it exists if (_templateFactory.FileExists(virtualPath)) return virtualPath; // If not, return null return null; } ////// Build the virtual path to the field template user control based on the template name and mode. /// By default, it returns names that look like TemplateName_ModeName.ascx, in the folder specified /// by TemplateFolderVirtualPath. /// /// /// /// ///public virtual string BuildVirtualPath(string templateName, MetaColumn column, DataBoundControlMode mode) { if (String.IsNullOrEmpty(templateName)) { throw new ArgumentNullException("templateName"); } string modePathModifier = null; switch (mode) { case DataBoundControlMode.ReadOnly: modePathModifier = String.Empty; break; case DataBoundControlMode.Edit: modePathModifier = FieldTemplateFactory.EditModePathModifier; break; case DataBoundControlMode.Insert: modePathModifier = FieldTemplateFactory.InsertModePathModifier; break; default: Debug.Assert(false); break; } return String.Format(CultureInfo.InvariantCulture, TemplateFolderVirtualPath + "{0}{1}.ascx", templateName, modePathModifier); } #region IFieldTemplateFactory Members public virtual void Initialize(MetaModel model) { Model = model; } /// /// See IFieldTemplateFactory for details. /// ///public virtual IFieldTemplate CreateFieldTemplate(MetaColumn column, DataBoundControlMode mode, string uiHint) { string fieldTemplatePath = GetFieldTemplateVirtualPathWithCaching(column, mode, uiHint); if (fieldTemplatePath == null) return null; return (IFieldTemplate)BuildManager.CreateInstanceFromVirtualPath( fieldTemplatePath, typeof(IFieldTemplate)); } #endregion } } // 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
- XmlIlVisitor.cs
- EditorPart.cs
- ReferenceService.cs
- ToolStripGripRenderEventArgs.cs
- SmtpNtlmAuthenticationModule.cs
- PageRanges.cs
- TextControl.cs
- ReadWriteSpinLock.cs
- ResourceExpression.cs
- WindowsSpinner.cs
- XmlComplianceUtil.cs
- PrintController.cs
- Thickness.cs
- StoreContentChangedEventArgs.cs
- FileDialogCustomPlace.cs
- ControlDesignerState.cs
- GridEntry.cs
- TextTreeDeleteContentUndoUnit.cs
- SqlSupersetValidator.cs
- PageSettings.cs
- Membership.cs
- CrossContextChannel.cs
- MediaContext.cs
- XmlArrayAttribute.cs
- Binding.cs
- ScrollChangedEventArgs.cs
- AllMembershipCondition.cs
- AddInAdapter.cs
- XmlValueConverter.cs
- TransportContext.cs
- NotificationContext.cs
- QuinticEase.cs
- UnsafeNativeMethods.cs
- MobileControlsSection.cs
- InfiniteIntConverter.cs
- DataGridViewTopLeftHeaderCell.cs
- RsaSecurityToken.cs
- OlePropertyStructs.cs
- OdbcCommand.cs
- OracleCommandSet.cs
- Sql8ConformanceChecker.cs
- PhonemeEventArgs.cs
- MILUtilities.cs
- Model3D.cs
- CustomGrammar.cs
- NCryptSafeHandles.cs
- embossbitmapeffect.cs
- WebPartDisplayModeCancelEventArgs.cs
- ApplicationSettingsBase.cs
- IdleTimeoutMonitor.cs
- MsmqTransportSecurityElement.cs
- ContextStaticAttribute.cs
- EpmContentSerializer.cs
- TypeElement.cs
- HostVisual.cs
- JumpTask.cs
- RadioButtonStandardAdapter.cs
- IPHostEntry.cs
- DockPattern.cs
- WindowsFormsSynchronizationContext.cs
- TableDetailsRow.cs
- HandlerBase.cs
- CodeTypeReferenceExpression.cs
- IISMapPath.cs
- GridViewCommandEventArgs.cs
- PropertyIDSet.cs
- Mappings.cs
- MetadataItemEmitter.cs
- Viewport2DVisual3D.cs
- HttpStreamMessage.cs
- Queue.cs
- CapabilitiesRule.cs
- Clipboard.cs
- RuntimeEnvironment.cs
- AssemblyFilter.cs
- Thumb.cs
- PieceNameHelper.cs
- WebPartDisplayMode.cs
- RuleInfoComparer.cs
- _IPv6Address.cs
- QuaternionAnimation.cs
- SkipQueryOptionExpression.cs
- ImageButton.cs
- MsmqIntegrationBinding.cs
- ComplexType.cs
- ExpandCollapsePattern.cs
- CodeValidator.cs
- BindingsCollection.cs
- MSAANativeProvider.cs
- EdmMember.cs
- SafeCancelMibChangeNotify.cs
- DataGridViewAutoSizeColumnModeEventArgs.cs
- ConnectorSelectionGlyph.cs
- XslTransform.cs
- ConfigXmlCDataSection.cs
- CommandSet.cs
- XmlSchemaProviderAttribute.cs
- FixedSOMPageElement.cs
- Pair.cs
- PointCollection.cs