Code:
/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / fx / src / WinForms / Managed / System / WinForms / formatter.cs / 2 / formatter.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Windows.Forms { using System; using System.ComponentModel; using System.Globalization; using System.Reflection; using System.Security; using System.Security.Permissions; internal class Formatter { static private Type stringType = typeof(String); static private Type booleanType = typeof(bool); static private Type checkStateType = typeof(CheckState); static private Object parseMethodNotFound = new Object(); static private Object defaultDataSourceNullValue = System.DBNull.Value; ////// /// Converts a binary value into a format suitable for display to the end user. /// Used when pushing a value from a back-end data source into a data-bound property on a control. /// /// The real conversion work happens inside FormatObjectInternal(). Before calling FormatObjectInternal(), /// we check for any use of nullable types or values (eg. Nullable public static object FormatObject(object value, Type targetType, TypeConverter sourceConverter, TypeConverter targetConverter, string formatString, IFormatProvider formatInfo, object formattedNullValue, object dataSourceNullValue) { // // On the way in, see if value represents 'null' for this back-end field type, and substitute DBNull. // For most types, 'null' is actually represented by DBNull. But for a nullable type, its represented // by an instance of that type with no value. And for business objects it may be represented by a // simple null reference. // if (Formatter.IsNullData(value, dataSourceNullValue)) { value = System.DBNull.Value; } // // Strip away any use of nullable types (eg. Nullable) and 'unwrap' them to get at the real /// types and values, which are then used in the actual conversion. If the caller is expecting a nullable /// value back, we must also re-wrap the final result inside a nullable value before returning. /// /// ), leaving just the 'real' types // Type oldTargetType = targetType; targetType = NullableUnwrap(targetType); sourceConverter = NullableUnwrap(sourceConverter); targetConverter = NullableUnwrap(targetConverter); bool isNullableTargetType = (targetType != oldTargetType); // // Call the 'real' method to perform the conversion // object result = FormatObjectInternal(value, targetType, sourceConverter, targetConverter, formatString, formatInfo, formattedNullValue); if (oldTargetType.IsValueType && result == null && !isNullableTargetType) { throw new FormatException(GetCantConvertMessage(value, targetType)); } return result; } /// /// /// Converts a value into a format suitable for display to the end user. /// /// - Converts DBNull or null into a suitable formatted representation of 'null' /// - Performs some special-case conversions (eg. Boolean to CheckState) /// - Uses TypeConverters or IConvertible where appropriate /// - Throws a FormatException is no suitable conversion can be found /// /// private static object FormatObjectInternal(object value, Type targetType, TypeConverter sourceConverter, TypeConverter targetConverter, string formatString, IFormatProvider formatInfo, object formattedNullValue) { if (value == System.DBNull.Value || value == null) { // // Convert DBNull to the formatted representation of 'null' (if possible) // if (formattedNullValue != null) { return formattedNullValue; } // // Convert DBNull or null to a specific 'known' representation of null (otherwise fail) // if (targetType == stringType) { return String.Empty; } if (targetType == checkStateType) { return CheckState.Indeterminate; } // Just pass null through: if this is a value type, it's been unwrapped here, so we return null // and the caller has to wrap if appropriate. return null; } // // Special case conversions // if (targetType == stringType) { if (value is IFormattable && !String.IsNullOrEmpty(formatString)) { return (value as IFormattable).ToString(formatString, formatInfo); } } //The converters for properties should take precedence. Unfortunately, we don't know whether we have one. Check vs. the //type's TypeConverter. We're punting the case where the property-provided converter is the same as the type's converter. Type sourceType = value.GetType(); TypeConverter sourceTypeTypeConverter = TypeDescriptor.GetConverter(sourceType); if (sourceConverter != null && sourceConverter != sourceTypeTypeConverter && sourceConverter.CanConvertTo(targetType)) { return sourceConverter.ConvertTo(null, GetFormatterCulture(formatInfo), value, targetType); } TypeConverter targetTypeTypeConverter = TypeDescriptor.GetConverter(targetType); if (targetConverter != null && targetConverter != targetTypeTypeConverter && targetConverter.CanConvertFrom(sourceType)) { return targetConverter.ConvertFrom(null, GetFormatterCulture(formatInfo), value); } if (targetType == checkStateType) { if (sourceType == booleanType) { return ((bool)value) ? CheckState.Checked : CheckState.Unchecked; } else { if (sourceConverter == null) { sourceConverter = sourceTypeTypeConverter; } if (sourceConverter != null && sourceConverter.CanConvertTo(booleanType)) { return (bool)sourceConverter.ConvertTo(null, GetFormatterCulture(formatInfo), value, booleanType) ? CheckState.Checked : CheckState.Unchecked; } } } if (targetType.IsAssignableFrom(sourceType)) { return value; } // // If explicit type converters not provided, supply default ones instead // if (sourceConverter == null) { sourceConverter = sourceTypeTypeConverter; } if (targetConverter == null) { targetConverter = targetTypeTypeConverter; } // // Standardized conversions // if (sourceConverter != null && sourceConverter.CanConvertTo(targetType)) { return sourceConverter.ConvertTo(null, GetFormatterCulture(formatInfo), value, targetType); } else if (targetConverter != null && targetConverter.CanConvertFrom(sourceType)) { return targetConverter.ConvertFrom(null, GetFormatterCulture(formatInfo), value); } else if (value is IConvertible) { return ChangeType(value, targetType, formatInfo); } // // Fail if no suitable conversion found // throw new FormatException(GetCantConvertMessage(value, targetType)); } ////// /// Converts a value entered by the end user (through UI) into the corresponding binary value. /// Used when pulling input from a data-bound property on a control to store in a back-end data source. /// /// The real conversion work happens inside ParseObjectInternal(). Before calling ParseObjectInternal(), /// we check for any use of nullable types or values (eg. Nullable public static object ParseObject(object value, Type targetType, Type sourceType, TypeConverter targetConverter, TypeConverter sourceConverter, IFormatProvider formatInfo, object formattedNullValue, object dataSourceNullValue) { // // Strip away any use of nullable types (eg. Nullable) and 'unwrap' them to get at the real /// types and values, which are then used in the actual conversion. If the caller is expecting a nullable /// value back, we must also re-wrap the final result inside a nullable value before returning. /// /// ), leaving just the 'real' types // Type oldTargetType = targetType; sourceType = NullableUnwrap(sourceType); targetType = NullableUnwrap(targetType); sourceConverter = NullableUnwrap(sourceConverter); targetConverter = NullableUnwrap(targetConverter); bool isNullableTargetType = (targetType != oldTargetType); // // Call the 'real' method to perform the conversion // object result = ParseObjectInternal(value, targetType, sourceType, targetConverter, sourceConverter, formatInfo, formattedNullValue); // // On the way out, substitute DBNull with the appropriate representation of 'null' for the final target type. // For most types, this is just DBNull. But for a nullable type, its an instance of that type with no value. // if (result == System.DBNull.Value) { return Formatter.NullData(oldTargetType, dataSourceNullValue); } return result; } /// /// /// Converts a value entered by the end user (through UI) into the corresponding binary value. /// /// - Converts formatted representations of 'null' into DBNull /// - Performs some special-case conversions (eg. CheckState to Boolean) /// - Uses TypeConverters or IConvertible where appropriate /// - Throws a FormatException is no suitable conversion can be found /// /// private static object ParseObjectInternal(object value, Type targetType, Type sourceType, TypeConverter targetConverter, TypeConverter sourceConverter, IFormatProvider formatInfo, object formattedNullValue) { // // Convert the formatted representation of 'null' to DBNull (if possible) // if (EqualsFormattedNullValue(value, formattedNullValue, formatInfo) || value == System.DBNull.Value) { return System.DBNull.Value; } // // Special case conversions // TypeConverter targetTypeTypeConverter = TypeDescriptor.GetConverter(targetType); if (targetConverter != null && targetTypeTypeConverter != targetConverter && targetConverter.CanConvertFrom(sourceType)) { return targetConverter.ConvertFrom(null, GetFormatterCulture(formatInfo), value); } TypeConverter sourceTypeTypeConverter = TypeDescriptor.GetConverter(sourceType); if (sourceConverter != null && sourceTypeTypeConverter != sourceConverter && sourceConverter.CanConvertTo(targetType)) { return sourceConverter.ConvertTo(null, GetFormatterCulture(formatInfo), value, targetType); } if (value is string) { // If target type has a suitable Parse method, use that to parse strings object parseResult = InvokeStringParseMethod(value, targetType, formatInfo); if (parseResult != parseMethodNotFound) { return parseResult; } } else if (value is CheckState) { CheckState state = (CheckState)value; if (state == CheckState.Indeterminate) { return DBNull.Value; } // Explicit conversion from CheckState to Boolean if (targetType == booleanType) { return (state == CheckState.Checked); } if (targetConverter == null) { targetConverter = targetTypeTypeConverter; } if (targetConverter != null && targetConverter.CanConvertFrom(booleanType)) { return targetConverter.ConvertFrom(null, GetFormatterCulture(formatInfo), state == CheckState.Checked); } } else if (value != null && targetType.IsAssignableFrom(value.GetType())) { // If value is already of a compatible type, just go ahead and use it return value; } // // If explicit type converters not provided, supply default ones instead // if (targetConverter == null) { targetConverter = targetTypeTypeConverter; } if (sourceConverter == null) { sourceConverter = sourceTypeTypeConverter; } // // Standardized conversions // if (targetConverter != null && targetConverter.CanConvertFrom(sourceType)) { return targetConverter.ConvertFrom(null, GetFormatterCulture(formatInfo), value); } else if (sourceConverter != null && sourceConverter.CanConvertTo(targetType)) { return sourceConverter.ConvertTo(null, GetFormatterCulture(formatInfo), value, targetType); } else if (value is IConvertible) { return ChangeType(value, targetType, formatInfo); } // // Fail if no suitable conversion found // throw new FormatException(GetCantConvertMessage(value, targetType)); } ////// Converts a value to the specified type using Convert.ChangeType() /// private static object ChangeType(object value, Type type, IFormatProvider formatInfo) { try { if (formatInfo == null) { formatInfo = CultureInfo.CurrentCulture; } return Convert.ChangeType(value, type, formatInfo); } catch (InvalidCastException ex) { throw new FormatException(ex.Message, ex); } } ////// Indicates whether the specified value matches the display-formatted representation of 'null data' for a given binding. /// private static bool EqualsFormattedNullValue(object value, object formattedNullValue, IFormatProvider formatInfo) { string formattedNullValueStr = formattedNullValue as string; string valueStr = value as string; if (formattedNullValueStr != null && valueStr != null) { // Use same optimization as in WindowsFormsUtils.SafeCompareStrings(...). This addresses bug DevDiv Bugs 110336. if (formattedNullValueStr.Length != valueStr.Length) { return false; } // Always do a case insensitive comparison for strings return String.Compare(valueStr, formattedNullValueStr, true, GetFormatterCulture(formatInfo)) == 0; } else { // Otherwise perform default comparison based on object types return Object.Equals(value, formattedNullValue); } } ////// Returns the FormatException message used when formatting/parsing fails to find any suitable conversion /// private static string GetCantConvertMessage(object value, Type targetType) { string stringResId = (value == null) ? SR.Formatter_CantConvertNull : SR.Formatter_CantConvert; return String.Format(CultureInfo.CurrentCulture, SR.GetString(stringResId), value, targetType.Name); } ////// Determines the correct culture to use during formatting and parsing /// private static CultureInfo GetFormatterCulture(IFormatProvider formatInfo) { if (formatInfo is CultureInfo) { return formatInfo as CultureInfo; } else { return CultureInfo.CurrentCulture; } } ////// Converts a value to the specified type using best Parse() method on that type /// public static object InvokeStringParseMethod(object value, Type targetType, IFormatProvider formatInfo) { try { MethodInfo mi; mi = targetType.GetMethod("Parse", BindingFlags.Public | BindingFlags.Static, null, new Type[] {stringType, typeof(System.Globalization.NumberStyles), typeof(System.IFormatProvider)}, null); if (mi != null) { return mi.Invoke(null, new object [] {(string) value, NumberStyles.Any, formatInfo}); } mi = targetType.GetMethod("Parse", BindingFlags.Public | BindingFlags.Static, null, new Type[] {stringType, typeof(System.IFormatProvider)}, null); if (mi != null) { return mi.Invoke(null, new object [] {(string) value, formatInfo}); } mi = targetType.GetMethod("Parse", BindingFlags.Public | BindingFlags.Static, null, new Type[] {stringType}, null); if (mi != null) { return mi.Invoke(null, new object [] {(string) value}); } return parseMethodNotFound; } catch (TargetInvocationException ex) { throw new FormatException(ex.InnerException.Message, ex.InnerException); } } ////// Indicates whether a given value represents 'null' for data source fields of the same type. /// public static bool IsNullData(object value, object dataSourceNullValue) { return value == null || value == System.DBNull.Value || Object.Equals(value, NullData(value.GetType(), dataSourceNullValue)); } ////// Returns the default representation of 'null' for a given data source field type. /// public static object NullData(Type type, object dataSourceNullValue) { if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) { // For nullable types, null is represented by an instance of that type with no assigned value. // The value could also be DBNull.Value (the default for dataSourceNullValue). if (dataSourceNullValue == null || dataSourceNullValue == DBNull.Value) { // We don't have a special value that represents null on the data source: // use the Nullable's representation return null; } else { return dataSourceNullValue; } } else { // For all other types, the default representation of null is defined by // the caller (this will usually be System.DBNull.Value for ADO.NET data // sources, or a null reference for 'business object' data sources). return dataSourceNullValue; } } /// /// Extract the inner type from a nullable type /// private static Type NullableUnwrap(Type type) { if (type == stringType) // ...performance optimization for the most common case return stringType; Type underlyingType = Nullable.GetUnderlyingType(type); return underlyingType ?? type; } ////// Extract the inner type converter from a nullable type converter /// private static TypeConverter NullableUnwrap(TypeConverter typeConverter) { NullableConverter nullableConverter = typeConverter as NullableConverter; return (nullableConverter != null) ? nullableConverter.UnderlyingTypeConverter : typeConverter; } public static object GetDefaultDataSourceNullValue(Type type) { return (type != null && !type.IsValueType) ? null : defaultDataSourceNullValue; } } } // 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
- BoolExpressionVisitors.cs
- PackageProperties.cs
- DataControlLinkButton.cs
- ControlTemplate.cs
- EdmComplexTypeAttribute.cs
- OutputCacheSection.cs
- DispatchProxy.cs
- QuadraticBezierSegment.cs
- TextServicesHost.cs
- VariableAction.cs
- InstalledVoice.cs
- SchemaElement.cs
- SQlBooleanStorage.cs
- TextBlock.cs
- Wildcard.cs
- AggregationMinMaxHelpers.cs
- IntPtr.cs
- ICspAsymmetricAlgorithm.cs
- Hashtable.cs
- EditorZone.cs
- XhtmlTextWriter.cs
- SymmetricKeyWrap.cs
- SHA256.cs
- Block.cs
- MeshGeometry3D.cs
- MemoryRecordBuffer.cs
- XmlQualifiedName.cs
- SiteOfOriginContainer.cs
- CharKeyFrameCollection.cs
- PeerTransportListenAddressValidator.cs
- TdsValueSetter.cs
- Compensate.cs
- UnionQueryOperator.cs
- WpfXamlLoader.cs
- CustomCredentialPolicy.cs
- Semaphore.cs
- MLangCodePageEncoding.cs
- IFlowDocumentViewer.cs
- KnownIds.cs
- InvalidFilterCriteriaException.cs
- CodeFieldReferenceExpression.cs
- FormsAuthenticationUser.cs
- SqlDataSourceConfigureSortForm.cs
- ExpressionEvaluator.cs
- PrintingPermission.cs
- EventLog.cs
- PageRanges.cs
- DataBindEngine.cs
- PickDesigner.xaml.cs
- ConfigurationManagerInternalFactory.cs
- Image.cs
- SafeFindHandle.cs
- WindowsToolbarItemAsMenuItem.cs
- GroupItem.cs
- RolePrincipal.cs
- Site.cs
- SiteMapNodeCollection.cs
- WebPartConnectionsCancelVerb.cs
- ListViewAutomationPeer.cs
- XamlToRtfWriter.cs
- XMLDiffLoader.cs
- TextSpanModifier.cs
- OleCmdHelper.cs
- ArcSegment.cs
- Point3DCollectionConverter.cs
- shaperfactoryquerycacheentry.cs
- RSAPKCS1KeyExchangeFormatter.cs
- ServiceOperationDetailViewControl.cs
- ObjectItemCollectionAssemblyCacheEntry.cs
- SynchronizationFilter.cs
- SoapSchemaExporter.cs
- FileFormatException.cs
- TextFindEngine.cs
- SymmetricAlgorithm.cs
- EntityDataSourceValidationException.cs
- DataServiceResponse.cs
- ComplexTypeEmitter.cs
- ParserHooks.cs
- EncodingNLS.cs
- SafeNativeMethods.cs
- ComboBox.cs
- ThreadLocal.cs
- RelatedCurrencyManager.cs
- ReceiveActivityDesigner.cs
- SystemKeyConverter.cs
- ListViewGroupConverter.cs
- TypeDelegator.cs
- SmtpClient.cs
- BaseAppDomainProtocolHandler.cs
- CodeNamespaceImport.cs
- PrivilegeNotHeldException.cs
- RSAPKCS1SignatureDeformatter.cs
- ItemContainerGenerator.cs
- DataGridViewColumnHeaderCell.cs
- basevalidator.cs
- BooleanConverter.cs
- EventMap.cs
- _LocalDataStoreMgr.cs
- HttpCacheVary.cs
- COM2TypeInfoProcessor.cs