FieldTemplateUserControl.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / xsp / System / DynamicData / DynamicData / FieldTemplateUserControl.cs / 1305376 / FieldTemplateUserControl.cs

                            using System.Collections; 
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations; 
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis; 
using System.Globalization; 
using System.Linq;
using System.Web.DynamicData.Util; 
using System.Web.Resources;
using System.Web.UI;
using System.Web.UI.WebControls;
 
namespace System.Web.DynamicData {
 
    ///  
    /// The base class for all field template user controls
    ///  
    public class FieldTemplateUserControl : UserControl, IBindableControl, IFieldTemplate {

        private static RequiredAttribute s_defaultRequiredAttribute = new RequiredAttribute();
        private Dictionary _ignoredModelValidationAttributes; 
        private object _fieldValue;
        private DefaultValueMapping _defaultValueMapping; 
        private bool _pageDataItemSet; 
        private object _pageDataItem;
 
        public FieldTemplateUserControl() {
        }

        internal FieldTemplateUserControl(DefaultValueMapping defaultValueMapping) { 
            _defaultValueMapping = defaultValueMapping;
        } 
 
        /// 
        /// The host that provides context to this field template 
        /// 
        [Browsable(false)]
        public IFieldTemplateHost Host { get; private set; }
 
        /// 
        /// The formatting options that need to be applied to this field template 
        ///  
        [Browsable(false)]
        public IFieldFormattingOptions FormattingOptions { get; private set; } 

        /// 
        /// The MetaColumn that this field template is working with
        ///  
        [Browsable(false)]
        public MetaColumn Column { 
            get { 
                return Host.Column;
            } 
        }

        /// 
        /// The ContainerType in which this 
        /// 
        [Browsable(false)] 
        public virtual ContainerType ContainerType { 
            get {
                return Misc.FindContainerType(this); 
            }
        }

        ///  
        /// The MetaTable that this field's column belongs to
        ///  
        [Browsable(false)] 
        public MetaTable Table {
            get { 
                return Column.Table;
            }
        }
 
        /// 
        /// Casts the MetaColumn to a MetaForeignKeyColumn. Throws if it is not an FK column. 
        ///  
        [Browsable(false)]
        public MetaForeignKeyColumn ForeignKeyColumn { 
            get {
                var foreignKeyColumn = Column as MetaForeignKeyColumn;
                if (foreignKeyColumn == null) {
                    throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, 
                        DynamicDataResources.FieldTemplateUserControl_ColumnIsNotFK, Column.Name));
                } 
                return foreignKeyColumn; 
            }
        } 

        /// 
        /// Casts the MetaColumn to a MetaChildrenColumn. Throws if it is not an Children column.
        ///  
        [Browsable(false)]
        public MetaChildrenColumn ChildrenColumn { 
            get { 
                var childrenColumn = Column as MetaChildrenColumn;
                if (childrenColumn == null) { 
                    throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture,
                        DynamicDataResources.FieldTemplateUserControl_ColumnIsNotChildren, Column.Name));
                }
                return childrenColumn; 
            }
        } 
 
        /// 
        /// The mode (readonly, edit, insert) that the field template should use 
        /// 
        [Browsable(false)]
        public DataBoundControlMode Mode {
            get { 
                return Host.Mode;
            } 
        } 

        ///  
        /// The collection of metadata attributes that apply to this column
        /// 
        [Browsable(false)]
        public System.ComponentModel.AttributeCollection MetadataAttributes { 
            get {
                return Column.Attributes; 
            } 
        }
 
        /// 
        /// Returns the data control that handles the field inside the field template
        /// 
        [Browsable(false)] 
        public virtual Control DataControl {
            get { 
                return null; 
            }
        } 

        /// 
        /// The current data object. Equivalent to Page.GetDataItem()
        ///  
        [Browsable(false)]
        public virtual object Row { 
            get { 
                // The DataItem is normally null in insert mode, we're going to surface the DictionaryCustomTypeDescriptor if there is a
                //  a default value was specified for this column. 
                if (Mode == DataBoundControlMode.Insert && DefaultValueMapping != null && DefaultValueMapping.Contains(Column)) {
                    return DefaultValueMapping.Instance;
                }
 
                // Used for unit testing. We can't use null since thats a valid value.
                if (_pageDataItemSet) { 
                    return _pageDataItem; 
                }
                return Page.GetDataItem(); 
            }
            internal set {
                // Only set in unit tests.
                _pageDataItem = value; 
                _pageDataItemSet = true;
            } 
        } 

        ///  
        /// The value of the Column in the current Row
        /// 
        [Browsable(false)]
        public virtual object FieldValue { 
            get {
                // If a field value was explicitly set, use it instead of the usual logic. 
                if (_fieldValue != null) 
                    return _fieldValue;
 
                return GetColumnValue(Column);
            }

            set { 
                _fieldValue = value;
            } 
        } 

        ///  
        /// Get the value of a specific column in the current row
        /// 
        /// 
        ///  
        protected virtual object GetColumnValue(MetaColumn column) {
            object row = Row; 
            if (row != null) { 
                return DataBinder.GetPropertyValue(row, column.Name);
            } 

            // Fallback on old behavior
            if (Mode == DataBoundControlMode.Insert) {
                return column.DefaultValue; 
            }
 
            return null; 
        }
 
        /// 
        /// Return the field value as a formatted string
        /// 
        [Browsable(false)] 
        public virtual string FieldValueString {
            get { 
                // Get the string and preprocess it 
                return FormatFieldValue(FieldValue);
            } 
        }

        /// 
        /// Similar to FieldValueString, but the string is to be used when the field is in edit mode 
        /// 
        [Browsable(false)] 
        public virtual string FieldValueEditString { 
            get {
                return FormattingOptions.FormatEditValue(FieldValue); 
            }
        }

        ///  
        /// Only applies to FK columns. Returns a URL that links to the page that displays the details
        /// of the foreign key entity. e.g. In the Product table's Category column, this produces a link 
        /// that goes to the details of the category that the product is in 
        /// 
        protected string ForeignKeyPath { 
            get {
                return ForeignKeyColumn.GetForeignKeyPath(PageAction.Details, Row);
            }
        } 

        internal DefaultValueMapping DefaultValueMapping { 
            get { 
                if (_defaultValueMapping == null) {
                    // Ensure this only gets accessed in insert mode 
                    Debug.Assert(Mode == DataBoundControlMode.Insert);
                    _defaultValueMapping = MetaTableHelper.GetDefaultValueMapping(this, Context.ToWrapper());
                }
                return _defaultValueMapping; 
            }
        } 
 
        /// 
        /// Same as ForeignKeyPath, except that it allows the path part of the URL to be overriden. This is 
        /// used when using pages that don't live under DynamicData/CustomPages.
        /// 
        /// The path override
        ///  
        protected string BuildForeignKeyPath(string path) {
            // If a path was passed in, resolved it relative to the containing page 
            if (!String.IsNullOrEmpty(path)) { 
                path = ResolveParentRelativePath(path);
            } 

            return ForeignKeyColumn.GetForeignKeyPath(PageAction.Details, Row, path);
        }
 
        /// 
        /// Only applies to Children columns. Returns a URL that links to the page that displays the list 
        /// of children entities. e.g. In the Category table's Products column, this produces a link 
        /// that goes to the list of Products that are in this Category.
        ///  
        protected string ChildrenPath {
            get {
                return ChildrenColumn.GetChildrenPath(PageAction.List, Row);
            } 
        }
 
        ///  
        /// Same as ChildrenPath, except that it allows the path part of the URL to be overriden. This is
        /// used when using pages that don't live under DynamicData/CustomPages. 
        /// 
        /// The path override
        /// 
        protected string BuildChildrenPath(string path) { 
            // If a path was passed in, resolved it relative to the containing page
            if (!String.IsNullOrEmpty(path)) { 
                path = ResolveParentRelativePath(path); 
            }
 
            return ChildrenColumn.GetChildrenPath(PageAction.List, Row, path);
        }

        // Resolve a relative path based on the containing page 
        private string ResolveParentRelativePath(string path) {
            if (path == null || TemplateControl == null) 
                return path; 

            Control parentControl = TemplateControl.Parent; 
            if (parentControl == null)
                return path;

            return parentControl.ResolveUrl(path); 
        }
 
        ///  
        /// Return the field template for another column
        ///  
        protected FieldTemplateUserControl FindOtherFieldTemplate(string columnName) {
            return Parent.FindFieldTemplate(columnName) as FieldTemplateUserControl;
        }
 
        /// 
        /// Only applies to FK columns. Populate the list control with all the values from the parent table 
        ///  
        /// The control to be populated
        protected void PopulateListControl(ListControl listControl) { 
            Type enumType;
            if (Column is MetaForeignKeyColumn) {
                Misc.FillListItemCollection(ForeignKeyColumn.ParentTable, listControl.Items);
            } else if (Column.IsEnumType(out enumType)) { 
                Debug.Assert(enumType != null);
                FillEnumListControl(listControl, enumType); 
            } 
        }
 
        private void FillEnumListControl(ListControl list, Type enumType) {
            foreach (DictionaryEntry entry in Misc.GetEnumNamesAndValues(enumType)) {
                list.Items.Add(new ListItem((string)entry.Key, (string)entry.Value));
            } 
        }
 
        ///  
        /// Gets a string representation of the column's value so that it can be matched with
        /// values populated in a dropdown. This currently works for FK and Enum columns only. 
        /// The method returns null for other column types.
        /// 
        /// 
        protected string GetSelectedValueString() { 
            Type enumType;
            if (Column is MetaForeignKeyColumn) { 
                return ForeignKeyColumn.GetForeignKeyString(Row); 
            } else if(Column.IsEnumType(out enumType)) {
                return Misc.GetUnderlyingTypeValueString(enumType, FieldValue); 
            }
            return null;
        }
 
        /// 
        /// Only applies to FK columns. This is used when saving the value of a foreign key, typically selected 
        /// from a drop down. 
        /// 
        /// The dictionary that contains all the new values 
        /// The value to be saved. Typically, this comes from DropDownList.SelectedValue
        protected virtual void ExtractForeignKey(IDictionary dictionary, string selectedValue) {
            ForeignKeyColumn.ExtractForeignKey(dictionary, selectedValue);
        } 

        ///  
        /// Apply potential HTML encoding and formatting to a string that needs to be displayed 
        /// 
        /// The value that should be formatted 
        /// the formatted value
        public virtual string FormatFieldValue(object fieldValue) {
            return FormattingOptions.FormatValue(fieldValue);
        } 

        ///  
        /// Return either the input value or null based on ConvertEmptyStringToNull and NullDisplayText 
        /// 
        /// The input value 
        /// The converted value
        protected virtual object ConvertEditedValue(string value) {
            return FormattingOptions.ConvertEditedValue(value);
        } 

        ///  
        /// Set up a validator for dynamic data use. It sets the ValidationGroup on all validators, 
        /// and also performs additional logic for some specific validator types. e.g. for a RangeValidator
        /// it sets the range values if they exist on the model. 
        /// 
        /// The validator to be set up
        [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly",
            Justification = "We really want Set Up as two words")] 
        protected virtual void SetUpValidator(BaseValidator validator) {
            SetUpValidator(validator, Column); 
        } 

        ///  
        /// Set up a validator for dynamic data use. It sets the ValidationGroup on all validators,
        /// and also performs additional logic for some specific validator types. e.g. for a RangeValidator
        /// it sets the range values if they exist on the model.
        ///  
        /// The validator to be set up
        /// The column for which the validator is getting set 
        [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", 
            Justification = "We really want Set Up as two words")]
        protected virtual void SetUpValidator(BaseValidator validator, MetaColumn column) { 

            // Set the validation group to match the dynamic control
            validator.ValidationGroup = Host.ValidationGroup;
 
            if (validator is DynamicValidator) {
                SetUpDynamicValidator((DynamicValidator)validator, column); 
            } 
            else if (validator is RequiredFieldValidator) {
                SetUpRequiredFieldValidator((RequiredFieldValidator)validator, column); 
            }
            else if (validator is CompareValidator) {
                SetUpCompareValidator((CompareValidator)validator, column);
            } 
            else if (validator is RangeValidator) {
                SetUpRangeValidator((RangeValidator)validator, column); 
            } 
            else if (validator is RegularExpressionValidator) {
                SetUpRegexValidator((RegularExpressionValidator)validator, column); 
            }

            validator.ToolTip = validator.ErrorMessage;
            validator.Text = "*"; 
        }
 
        private void SetUpDynamicValidator(DynamicValidator validator, MetaColumn column) { 
            validator.Column = column;
 
            // Tell the DynamicValidator which validation attributes it should ignore (because
            // they're already handled by server side ASP.NET validator controls)
            validator.SetIgnoredModelValidationAttributes(_ignoredModelValidationAttributes);
        } 

        private void SetUpRequiredFieldValidator(RequiredFieldValidator validator, MetaColumn column) { 
            var requiredAttribute = column.Metadata.RequiredAttribute; 
            if (requiredAttribute!= null && requiredAttribute.AllowEmptyStrings) {
                // Dev10 Bug 749744 
                // If somone explicitly set AllowEmptyStrings = true then we assume that they want to
                // allow empty strings to go into a database even if the column is marked as required.
                // Since ASP.NET validators always get an empty string, this essential turns of
                // required field validation. 
                IgnoreModelValidationAttribute(typeof(RequiredAttribute));
            } else if (column.IsRequired) { 
                validator.Enabled = true; 

                // Make sure the attribute doesn't get validated a second time by the DynamicValidator 
                IgnoreModelValidationAttribute(typeof(RequiredAttribute));

                if (String.IsNullOrEmpty(validator.ErrorMessage)) {
                    string columnErrorMessage = column.RequiredErrorMessage; 
                    if (String.IsNullOrEmpty(columnErrorMessage)) {
                        // generate default error message 
                        validator.ErrorMessage = HttpUtility.HtmlEncode(s_defaultRequiredAttribute.FormatErrorMessage(column.DisplayName)); 
                    } else {
                        validator.ErrorMessage = HttpUtility.HtmlEncode(columnErrorMessage); 
                    }
                }
            }
        } 

        private void SetUpCompareValidator(CompareValidator validator, MetaColumn column) { 
            validator.Operator = ValidationCompareOperator.DataTypeCheck; 

            ValidationDataType? dataType = null; 
            string errorMessage = null;
            if (column.ColumnType == typeof(DateTime)) {
                dataType = ValidationDataType.Date;
                errorMessage = String.Format(CultureInfo.CurrentCulture, 
                    DynamicDataResources.FieldTemplateUserControl_CompareValidationError_Date,
                    column.DisplayName); 
            } else if (column.IsInteger && column.ColumnType != typeof(long)) { 
                // long is unsupported because it's larger than int
                dataType = ValidationDataType.Integer; 
                errorMessage = String.Format(CultureInfo.CurrentCulture,
                    DynamicDataResources.FieldTemplateUserControl_CompareValidationError_Integer,
                    column.DisplayName);
            } else if (column.ColumnType == typeof(decimal)) { 
                //
 
                dataType = ValidationDataType.Double; 
                errorMessage = String.Format(CultureInfo.CurrentCulture,
                    DynamicDataResources.FieldTemplateUserControl_CompareValidationError_Decimal, 
                    column.DisplayName);
            } else if (column.IsFloatingPoint) {
                dataType = ValidationDataType.Double;
                errorMessage = String.Format(CultureInfo.CurrentCulture, 
                    DynamicDataResources.FieldTemplateUserControl_CompareValidationError_Decimal,
                    column.DisplayName); 
            } 

            if (dataType != null) { 
                Debug.Assert(errorMessage != null);
                validator.Enabled = true;
                validator.Type = dataType.Value;
                if (String.IsNullOrEmpty(validator.ErrorMessage)) { 
                    validator.ErrorMessage = HttpUtility.HtmlEncode(errorMessage);
                } 
            } else { 
                // If we don't recognize the type, turn off the validator
                validator.Enabled = false; 
            }
        }

        private void SetUpRangeValidator(RangeValidator validator, MetaColumn column) { 
            // Nothing to do if no range was specified
            var rangeAttribute = column.Attributes.OfType().FirstOrDefault(); 
            if (rangeAttribute == null) 
                return;
 
            // Make sure the attribute doesn't get validated a second time by the DynamicValidator
            IgnoreModelValidationAttribute(rangeAttribute.GetType());

            validator.Enabled = true; 

            Func converter; 
            switch (validator.Type) { 
                case ValidationDataType.Integer:
                    converter = val => Convert.ToInt32(val, CultureInfo.InvariantCulture).ToString(CultureInfo.InvariantCulture); 
                    break;
                case ValidationDataType.Double:
                    converter = val => Convert.ToDouble(val, CultureInfo.InvariantCulture).ToString(CultureInfo.InvariantCulture);
                    break; 
                case ValidationDataType.String:
                default: 
                    converter = val => val.ToString(); 
                    break;
            } 
            validator.MinimumValue = converter(rangeAttribute.Minimum);
            validator.MaximumValue = converter(rangeAttribute.Maximum);

            if (String.IsNullOrEmpty(validator.ErrorMessage)) { 
                validator.ErrorMessage = HttpUtility.HtmlEncode(rangeAttribute.FormatErrorMessage(column.DisplayName));
            } 
        } 

        private void SetUpRegexValidator(RegularExpressionValidator validator, MetaColumn column) { 
            // Nothing to do if no regex was specified
            var regexAttribute = column.Attributes.OfType().FirstOrDefault();
            if (regexAttribute == null)
                return; 

            // Make sure the attribute doesn't get validated a second time by the DynamicValidator 
            IgnoreModelValidationAttribute(regexAttribute.GetType()); 

            validator.Enabled = true; 
            validator.ValidationExpression = regexAttribute.Pattern;

            if (String.IsNullOrEmpty(validator.ErrorMessage)) {
                validator.ErrorMessage = HttpUtility.HtmlEncode(regexAttribute.FormatErrorMessage(column.DisplayName)); 
            }
        } 
 
        /// 
        /// This method instructs the DynamicValidator to ignore a specific type of model 
        /// validation attributes. This is called when that attribute type is already being
        /// fully handled by an ASP.NET validator controls. Without this call, the validation
        /// could happen twice, resulting in a duplicated error message
        ///  
        protected void IgnoreModelValidationAttribute(Type attributeType) {
            // Create the dictionary on demand 
            if (_ignoredModelValidationAttributes == null) { 
                _ignoredModelValidationAttributes = new Dictionary();
            } 

            // Add the attribute type to the list
            _ignoredModelValidationAttributes[attributeType] = true;
        } 

        ///  
        /// Implementation of IBindableControl.ExtractValues 
        /// 
        /// The dictionary that contains all the new values 
        protected virtual void ExtractValues(IOrderedDictionary dictionary) {
            // To nothing in the base class.  Derived field templates decide what they want to save
        }
 
        #region IBindableControl Members
 
        void IBindableControl.ExtractValues(IOrderedDictionary dictionary) { 
            ExtractValues(dictionary);
        } 

        #endregion

        #region IFieldTemplate Members 

        void IFieldTemplate.SetHost(IFieldTemplateHost host) { 
            Host = host; 
            FormattingOptions = Host.FormattingOptions;
        } 

        #endregion
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System.Collections; 
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations; 
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis; 
using System.Globalization; 
using System.Linq;
using System.Web.DynamicData.Util; 
using System.Web.Resources;
using System.Web.UI;
using System.Web.UI.WebControls;
 
namespace System.Web.DynamicData {
 
    ///  
    /// The base class for all field template user controls
    ///  
    public class FieldTemplateUserControl : UserControl, IBindableControl, IFieldTemplate {

        private static RequiredAttribute s_defaultRequiredAttribute = new RequiredAttribute();
        private Dictionary _ignoredModelValidationAttributes; 
        private object _fieldValue;
        private DefaultValueMapping _defaultValueMapping; 
        private bool _pageDataItemSet; 
        private object _pageDataItem;
 
        public FieldTemplateUserControl() {
        }

        internal FieldTemplateUserControl(DefaultValueMapping defaultValueMapping) { 
            _defaultValueMapping = defaultValueMapping;
        } 
 
        /// 
        /// The host that provides context to this field template 
        /// 
        [Browsable(false)]
        public IFieldTemplateHost Host { get; private set; }
 
        /// 
        /// The formatting options that need to be applied to this field template 
        ///  
        [Browsable(false)]
        public IFieldFormattingOptions FormattingOptions { get; private set; } 

        /// 
        /// The MetaColumn that this field template is working with
        ///  
        [Browsable(false)]
        public MetaColumn Column { 
            get { 
                return Host.Column;
            } 
        }

        /// 
        /// The ContainerType in which this 
        /// 
        [Browsable(false)] 
        public virtual ContainerType ContainerType { 
            get {
                return Misc.FindContainerType(this); 
            }
        }

        ///  
        /// The MetaTable that this field's column belongs to
        ///  
        [Browsable(false)] 
        public MetaTable Table {
            get { 
                return Column.Table;
            }
        }
 
        /// 
        /// Casts the MetaColumn to a MetaForeignKeyColumn. Throws if it is not an FK column. 
        ///  
        [Browsable(false)]
        public MetaForeignKeyColumn ForeignKeyColumn { 
            get {
                var foreignKeyColumn = Column as MetaForeignKeyColumn;
                if (foreignKeyColumn == null) {
                    throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, 
                        DynamicDataResources.FieldTemplateUserControl_ColumnIsNotFK, Column.Name));
                } 
                return foreignKeyColumn; 
            }
        } 

        /// 
        /// Casts the MetaColumn to a MetaChildrenColumn. Throws if it is not an Children column.
        ///  
        [Browsable(false)]
        public MetaChildrenColumn ChildrenColumn { 
            get { 
                var childrenColumn = Column as MetaChildrenColumn;
                if (childrenColumn == null) { 
                    throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture,
                        DynamicDataResources.FieldTemplateUserControl_ColumnIsNotChildren, Column.Name));
                }
                return childrenColumn; 
            }
        } 
 
        /// 
        /// The mode (readonly, edit, insert) that the field template should use 
        /// 
        [Browsable(false)]
        public DataBoundControlMode Mode {
            get { 
                return Host.Mode;
            } 
        } 

        ///  
        /// The collection of metadata attributes that apply to this column
        /// 
        [Browsable(false)]
        public System.ComponentModel.AttributeCollection MetadataAttributes { 
            get {
                return Column.Attributes; 
            } 
        }
 
        /// 
        /// Returns the data control that handles the field inside the field template
        /// 
        [Browsable(false)] 
        public virtual Control DataControl {
            get { 
                return null; 
            }
        } 

        /// 
        /// The current data object. Equivalent to Page.GetDataItem()
        ///  
        [Browsable(false)]
        public virtual object Row { 
            get { 
                // The DataItem is normally null in insert mode, we're going to surface the DictionaryCustomTypeDescriptor if there is a
                //  a default value was specified for this column. 
                if (Mode == DataBoundControlMode.Insert && DefaultValueMapping != null && DefaultValueMapping.Contains(Column)) {
                    return DefaultValueMapping.Instance;
                }
 
                // Used for unit testing. We can't use null since thats a valid value.
                if (_pageDataItemSet) { 
                    return _pageDataItem; 
                }
                return Page.GetDataItem(); 
            }
            internal set {
                // Only set in unit tests.
                _pageDataItem = value; 
                _pageDataItemSet = true;
            } 
        } 

        ///  
        /// The value of the Column in the current Row
        /// 
        [Browsable(false)]
        public virtual object FieldValue { 
            get {
                // If a field value was explicitly set, use it instead of the usual logic. 
                if (_fieldValue != null) 
                    return _fieldValue;
 
                return GetColumnValue(Column);
            }

            set { 
                _fieldValue = value;
            } 
        } 

        ///  
        /// Get the value of a specific column in the current row
        /// 
        /// 
        ///  
        protected virtual object GetColumnValue(MetaColumn column) {
            object row = Row; 
            if (row != null) { 
                return DataBinder.GetPropertyValue(row, column.Name);
            } 

            // Fallback on old behavior
            if (Mode == DataBoundControlMode.Insert) {
                return column.DefaultValue; 
            }
 
            return null; 
        }
 
        /// 
        /// Return the field value as a formatted string
        /// 
        [Browsable(false)] 
        public virtual string FieldValueString {
            get { 
                // Get the string and preprocess it 
                return FormatFieldValue(FieldValue);
            } 
        }

        /// 
        /// Similar to FieldValueString, but the string is to be used when the field is in edit mode 
        /// 
        [Browsable(false)] 
        public virtual string FieldValueEditString { 
            get {
                return FormattingOptions.FormatEditValue(FieldValue); 
            }
        }

        ///  
        /// Only applies to FK columns. Returns a URL that links to the page that displays the details
        /// of the foreign key entity. e.g. In the Product table's Category column, this produces a link 
        /// that goes to the details of the category that the product is in 
        /// 
        protected string ForeignKeyPath { 
            get {
                return ForeignKeyColumn.GetForeignKeyPath(PageAction.Details, Row);
            }
        } 

        internal DefaultValueMapping DefaultValueMapping { 
            get { 
                if (_defaultValueMapping == null) {
                    // Ensure this only gets accessed in insert mode 
                    Debug.Assert(Mode == DataBoundControlMode.Insert);
                    _defaultValueMapping = MetaTableHelper.GetDefaultValueMapping(this, Context.ToWrapper());
                }
                return _defaultValueMapping; 
            }
        } 
 
        /// 
        /// Same as ForeignKeyPath, except that it allows the path part of the URL to be overriden. This is 
        /// used when using pages that don't live under DynamicData/CustomPages.
        /// 
        /// The path override
        ///  
        protected string BuildForeignKeyPath(string path) {
            // If a path was passed in, resolved it relative to the containing page 
            if (!String.IsNullOrEmpty(path)) { 
                path = ResolveParentRelativePath(path);
            } 

            return ForeignKeyColumn.GetForeignKeyPath(PageAction.Details, Row, path);
        }
 
        /// 
        /// Only applies to Children columns. Returns a URL that links to the page that displays the list 
        /// of children entities. e.g. In the Category table's Products column, this produces a link 
        /// that goes to the list of Products that are in this Category.
        ///  
        protected string ChildrenPath {
            get {
                return ChildrenColumn.GetChildrenPath(PageAction.List, Row);
            } 
        }
 
        ///  
        /// Same as ChildrenPath, except that it allows the path part of the URL to be overriden. This is
        /// used when using pages that don't live under DynamicData/CustomPages. 
        /// 
        /// The path override
        /// 
        protected string BuildChildrenPath(string path) { 
            // If a path was passed in, resolved it relative to the containing page
            if (!String.IsNullOrEmpty(path)) { 
                path = ResolveParentRelativePath(path); 
            }
 
            return ChildrenColumn.GetChildrenPath(PageAction.List, Row, path);
        }

        // Resolve a relative path based on the containing page 
        private string ResolveParentRelativePath(string path) {
            if (path == null || TemplateControl == null) 
                return path; 

            Control parentControl = TemplateControl.Parent; 
            if (parentControl == null)
                return path;

            return parentControl.ResolveUrl(path); 
        }
 
        ///  
        /// Return the field template for another column
        ///  
        protected FieldTemplateUserControl FindOtherFieldTemplate(string columnName) {
            return Parent.FindFieldTemplate(columnName) as FieldTemplateUserControl;
        }
 
        /// 
        /// Only applies to FK columns. Populate the list control with all the values from the parent table 
        ///  
        /// The control to be populated
        protected void PopulateListControl(ListControl listControl) { 
            Type enumType;
            if (Column is MetaForeignKeyColumn) {
                Misc.FillListItemCollection(ForeignKeyColumn.ParentTable, listControl.Items);
            } else if (Column.IsEnumType(out enumType)) { 
                Debug.Assert(enumType != null);
                FillEnumListControl(listControl, enumType); 
            } 
        }
 
        private void FillEnumListControl(ListControl list, Type enumType) {
            foreach (DictionaryEntry entry in Misc.GetEnumNamesAndValues(enumType)) {
                list.Items.Add(new ListItem((string)entry.Key, (string)entry.Value));
            } 
        }
 
        ///  
        /// Gets a string representation of the column's value so that it can be matched with
        /// values populated in a dropdown. This currently works for FK and Enum columns only. 
        /// The method returns null for other column types.
        /// 
        /// 
        protected string GetSelectedValueString() { 
            Type enumType;
            if (Column is MetaForeignKeyColumn) { 
                return ForeignKeyColumn.GetForeignKeyString(Row); 
            } else if(Column.IsEnumType(out enumType)) {
                return Misc.GetUnderlyingTypeValueString(enumType, FieldValue); 
            }
            return null;
        }
 
        /// 
        /// Only applies to FK columns. This is used when saving the value of a foreign key, typically selected 
        /// from a drop down. 
        /// 
        /// The dictionary that contains all the new values 
        /// The value to be saved. Typically, this comes from DropDownList.SelectedValue
        protected virtual void ExtractForeignKey(IDictionary dictionary, string selectedValue) {
            ForeignKeyColumn.ExtractForeignKey(dictionary, selectedValue);
        } 

        ///  
        /// Apply potential HTML encoding and formatting to a string that needs to be displayed 
        /// 
        /// The value that should be formatted 
        /// the formatted value
        public virtual string FormatFieldValue(object fieldValue) {
            return FormattingOptions.FormatValue(fieldValue);
        } 

        ///  
        /// Return either the input value or null based on ConvertEmptyStringToNull and NullDisplayText 
        /// 
        /// The input value 
        /// The converted value
        protected virtual object ConvertEditedValue(string value) {
            return FormattingOptions.ConvertEditedValue(value);
        } 

        ///  
        /// Set up a validator for dynamic data use. It sets the ValidationGroup on all validators, 
        /// and also performs additional logic for some specific validator types. e.g. for a RangeValidator
        /// it sets the range values if they exist on the model. 
        /// 
        /// The validator to be set up
        [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly",
            Justification = "We really want Set Up as two words")] 
        protected virtual void SetUpValidator(BaseValidator validator) {
            SetUpValidator(validator, Column); 
        } 

        ///  
        /// Set up a validator for dynamic data use. It sets the ValidationGroup on all validators,
        /// and also performs additional logic for some specific validator types. e.g. for a RangeValidator
        /// it sets the range values if they exist on the model.
        ///  
        /// The validator to be set up
        /// The column for which the validator is getting set 
        [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", 
            Justification = "We really want Set Up as two words")]
        protected virtual void SetUpValidator(BaseValidator validator, MetaColumn column) { 

            // Set the validation group to match the dynamic control
            validator.ValidationGroup = Host.ValidationGroup;
 
            if (validator is DynamicValidator) {
                SetUpDynamicValidator((DynamicValidator)validator, column); 
            } 
            else if (validator is RequiredFieldValidator) {
                SetUpRequiredFieldValidator((RequiredFieldValidator)validator, column); 
            }
            else if (validator is CompareValidator) {
                SetUpCompareValidator((CompareValidator)validator, column);
            } 
            else if (validator is RangeValidator) {
                SetUpRangeValidator((RangeValidator)validator, column); 
            } 
            else if (validator is RegularExpressionValidator) {
                SetUpRegexValidator((RegularExpressionValidator)validator, column); 
            }

            validator.ToolTip = validator.ErrorMessage;
            validator.Text = "*"; 
        }
 
        private void SetUpDynamicValidator(DynamicValidator validator, MetaColumn column) { 
            validator.Column = column;
 
            // Tell the DynamicValidator which validation attributes it should ignore (because
            // they're already handled by server side ASP.NET validator controls)
            validator.SetIgnoredModelValidationAttributes(_ignoredModelValidationAttributes);
        } 

        private void SetUpRequiredFieldValidator(RequiredFieldValidator validator, MetaColumn column) { 
            var requiredAttribute = column.Metadata.RequiredAttribute; 
            if (requiredAttribute!= null && requiredAttribute.AllowEmptyStrings) {
                // Dev10 Bug 749744 
                // If somone explicitly set AllowEmptyStrings = true then we assume that they want to
                // allow empty strings to go into a database even if the column is marked as required.
                // Since ASP.NET validators always get an empty string, this essential turns of
                // required field validation. 
                IgnoreModelValidationAttribute(typeof(RequiredAttribute));
            } else if (column.IsRequired) { 
                validator.Enabled = true; 

                // Make sure the attribute doesn't get validated a second time by the DynamicValidator 
                IgnoreModelValidationAttribute(typeof(RequiredAttribute));

                if (String.IsNullOrEmpty(validator.ErrorMessage)) {
                    string columnErrorMessage = column.RequiredErrorMessage; 
                    if (String.IsNullOrEmpty(columnErrorMessage)) {
                        // generate default error message 
                        validator.ErrorMessage = HttpUtility.HtmlEncode(s_defaultRequiredAttribute.FormatErrorMessage(column.DisplayName)); 
                    } else {
                        validator.ErrorMessage = HttpUtility.HtmlEncode(columnErrorMessage); 
                    }
                }
            }
        } 

        private void SetUpCompareValidator(CompareValidator validator, MetaColumn column) { 
            validator.Operator = ValidationCompareOperator.DataTypeCheck; 

            ValidationDataType? dataType = null; 
            string errorMessage = null;
            if (column.ColumnType == typeof(DateTime)) {
                dataType = ValidationDataType.Date;
                errorMessage = String.Format(CultureInfo.CurrentCulture, 
                    DynamicDataResources.FieldTemplateUserControl_CompareValidationError_Date,
                    column.DisplayName); 
            } else if (column.IsInteger && column.ColumnType != typeof(long)) { 
                // long is unsupported because it's larger than int
                dataType = ValidationDataType.Integer; 
                errorMessage = String.Format(CultureInfo.CurrentCulture,
                    DynamicDataResources.FieldTemplateUserControl_CompareValidationError_Integer,
                    column.DisplayName);
            } else if (column.ColumnType == typeof(decimal)) { 
                //
 
                dataType = ValidationDataType.Double; 
                errorMessage = String.Format(CultureInfo.CurrentCulture,
                    DynamicDataResources.FieldTemplateUserControl_CompareValidationError_Decimal, 
                    column.DisplayName);
            } else if (column.IsFloatingPoint) {
                dataType = ValidationDataType.Double;
                errorMessage = String.Format(CultureInfo.CurrentCulture, 
                    DynamicDataResources.FieldTemplateUserControl_CompareValidationError_Decimal,
                    column.DisplayName); 
            } 

            if (dataType != null) { 
                Debug.Assert(errorMessage != null);
                validator.Enabled = true;
                validator.Type = dataType.Value;
                if (String.IsNullOrEmpty(validator.ErrorMessage)) { 
                    validator.ErrorMessage = HttpUtility.HtmlEncode(errorMessage);
                } 
            } else { 
                // If we don't recognize the type, turn off the validator
                validator.Enabled = false; 
            }
        }

        private void SetUpRangeValidator(RangeValidator validator, MetaColumn column) { 
            // Nothing to do if no range was specified
            var rangeAttribute = column.Attributes.OfType().FirstOrDefault(); 
            if (rangeAttribute == null) 
                return;
 
            // Make sure the attribute doesn't get validated a second time by the DynamicValidator
            IgnoreModelValidationAttribute(rangeAttribute.GetType());

            validator.Enabled = true; 

            Func converter; 
            switch (validator.Type) { 
                case ValidationDataType.Integer:
                    converter = val => Convert.ToInt32(val, CultureInfo.InvariantCulture).ToString(CultureInfo.InvariantCulture); 
                    break;
                case ValidationDataType.Double:
                    converter = val => Convert.ToDouble(val, CultureInfo.InvariantCulture).ToString(CultureInfo.InvariantCulture);
                    break; 
                case ValidationDataType.String:
                default: 
                    converter = val => val.ToString(); 
                    break;
            } 
            validator.MinimumValue = converter(rangeAttribute.Minimum);
            validator.MaximumValue = converter(rangeAttribute.Maximum);

            if (String.IsNullOrEmpty(validator.ErrorMessage)) { 
                validator.ErrorMessage = HttpUtility.HtmlEncode(rangeAttribute.FormatErrorMessage(column.DisplayName));
            } 
        } 

        private void SetUpRegexValidator(RegularExpressionValidator validator, MetaColumn column) { 
            // Nothing to do if no regex was specified
            var regexAttribute = column.Attributes.OfType().FirstOrDefault();
            if (regexAttribute == null)
                return; 

            // Make sure the attribute doesn't get validated a second time by the DynamicValidator 
            IgnoreModelValidationAttribute(regexAttribute.GetType()); 

            validator.Enabled = true; 
            validator.ValidationExpression = regexAttribute.Pattern;

            if (String.IsNullOrEmpty(validator.ErrorMessage)) {
                validator.ErrorMessage = HttpUtility.HtmlEncode(regexAttribute.FormatErrorMessage(column.DisplayName)); 
            }
        } 
 
        /// 
        /// This method instructs the DynamicValidator to ignore a specific type of model 
        /// validation attributes. This is called when that attribute type is already being
        /// fully handled by an ASP.NET validator controls. Without this call, the validation
        /// could happen twice, resulting in a duplicated error message
        ///  
        protected void IgnoreModelValidationAttribute(Type attributeType) {
            // Create the dictionary on demand 
            if (_ignoredModelValidationAttributes == null) { 
                _ignoredModelValidationAttributes = new Dictionary();
            } 

            // Add the attribute type to the list
            _ignoredModelValidationAttributes[attributeType] = true;
        } 

        ///  
        /// Implementation of IBindableControl.ExtractValues 
        /// 
        /// The dictionary that contains all the new values 
        protected virtual void ExtractValues(IOrderedDictionary dictionary) {
            // To nothing in the base class.  Derived field templates decide what they want to save
        }
 
        #region IBindableControl Members
 
        void IBindableControl.ExtractValues(IOrderedDictionary dictionary) { 
            ExtractValues(dictionary);
        } 

        #endregion

        #region IFieldTemplate Members 

        void IFieldTemplate.SetHost(IFieldTemplateHost host) { 
            Host = host; 
            FormattingOptions = Host.FormattingOptions;
        } 

        #endregion
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK