Code:
/ DotNET / DotNET / 8.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
- IDReferencePropertyAttribute.cs
- Padding.cs
- VisualBrush.cs
- ContextMenuStrip.cs
- PortCache.cs
- SliderAutomationPeer.cs
- WeakEventManager.cs
- XPathParser.cs
- XpsFilter.cs
- _SSPISessionCache.cs
- GcSettings.cs
- UnsafeNativeMethods.cs
- Label.cs
- PartialCachingAttribute.cs
- DbParameterCollection.cs
- ControlTemplate.cs
- ContainerUtilities.cs
- BinaryMethodMessage.cs
- PerformanceCounterCategory.cs
- BamlWriter.cs
- EdmToObjectNamespaceMap.cs
- WSFederationHttpBindingCollectionElement.cs
- PackWebRequestFactory.cs
- ObjectStateManager.cs
- CmsInterop.cs
- _BaseOverlappedAsyncResult.cs
- BindingMemberInfo.cs
- WindowsFormsSynchronizationContext.cs
- ImageKeyConverter.cs
- Visitors.cs
- GPStream.cs
- XmlConvert.cs
- DragEvent.cs
- AttachmentService.cs
- OdbcException.cs
- ThrowHelper.cs
- TreePrinter.cs
- IconConverter.cs
- ColorPalette.cs
- QueryAccessibilityHelpEvent.cs
- ConstructorBuilder.cs
- ToolStripItemEventArgs.cs
- Point3DCollection.cs
- Mapping.cs
- MetadataElement.cs
- RightsManagementEncryptedStream.cs
- WebServiceClientProxyGenerator.cs
- SignerInfo.cs
- UriSection.cs
- ProfileElement.cs
- HashAlgorithm.cs
- WorkflowRuntimeServiceElement.cs
- SqlColumnizer.cs
- ParentUndoUnit.cs
- Delegate.cs
- HtmlWindowCollection.cs
- PrimitiveSchema.cs
- Vertex.cs
- FileDataSourceCache.cs
- PropertyDescriptor.cs
- HttpProfileGroupBase.cs
- SoundPlayerAction.cs
- ConfigurationSectionGroup.cs
- TextBox.cs
- FamilyMapCollection.cs
- HwndSubclass.cs
- FocusChangedEventArgs.cs
- DesignerTransactionCloseEvent.cs
- GridPatternIdentifiers.cs
- Window.cs
- TextControl.cs
- BoundField.cs
- SessionPageStatePersister.cs
- EntityDataSourceEntityTypeFilterConverter.cs
- IncrementalReadDecoders.cs
- UserControl.cs
- CustomCategoryAttribute.cs
- cookiecontainer.cs
- HiddenFieldPageStatePersister.cs
- PointValueSerializer.cs
- OleDbConnectionPoolGroupProviderInfo.cs
- CmsUtils.cs
- IQueryable.cs
- ImmutableCollection.cs
- PerformanceCounterPermission.cs
- PixelShader.cs
- FormatterServices.cs
- EventProvider.cs
- SqlConnectionFactory.cs
- TreeNodeCollection.cs
- SystemEvents.cs
- ImagingCache.cs
- DataListItem.cs
- ServiceNameElement.cs
- TemplateBuilder.cs
- TreeIterator.cs
- TableDetailsRow.cs
- XmlTextReaderImpl.cs
- InstanceStore.cs
- SafeRightsManagementPubHandle.cs