| File: System\ComponentModel\ReferenceConverter.cs | Web Access |
| Project: src\runtime\src\libraries\System.ComponentModel.TypeConverter\src\System.ComponentModel.TypeConverter.csproj (System.ComponentModel.TypeConverter) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections; using System.Collections.Generic; using System.ComponentModel.Design; using System.Globalization; using System.Runtime.InteropServices; namespace System.ComponentModel { /// <summary> /// Provides a type converter to convert object references to and from various /// other representations. /// </summary> public class ReferenceConverter : TypeConverter { private static readonly string s_none = SR.UsingResourceKeys() ? "(none)" : SR.toStringNone; private readonly Type _type; /// <summary> /// Initializes a new instance of the <see cref='System.ComponentModel.ReferenceConverter'/> class. /// </summary> public ReferenceConverter(Type type) { _type = type; } /// <summary> /// Gets a value indicating whether this converter can convert an object in the /// given source type to a reference object using the specified context. /// </summary> public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType) { if (sourceType == typeof(string) && context != null) { return true; } return base.CanConvertFrom(context, sourceType); } /// <summary> /// Converts the given object to the reference type. /// </summary> public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value) { if (value is string text) { text = text.Trim(); if (!string.Equals(text, s_none) && context != null) { // Try the reference service first. if (context.GetService(typeof(IReferenceService)) is IReferenceService refSvc) { object? obj = refSvc.GetReference(text); if (obj != null) { return obj; } } // Now try IContainer IContainer? cont = context.Container; if (cont != null) { object? obj = cont.Components[text]; if (obj != null) { return obj; } } } return null; } return base.ConvertFrom(context, culture, value); } /// <summary> /// Converts the given value object to the reference type using the specified context and arguments. /// </summary> public override object? ConvertTo(ITypeDescriptorContext? context, CultureInfo? culture, object? value, Type destinationType) { if (destinationType == typeof(string)) { if (value != null) { // Try the reference service first. if (context?.GetService(typeof(IReferenceService)) is IReferenceService refSvc) { string? name = refSvc.GetName(value); if (name != null) { return name; } } // Now see if this is an IComponent. if (!Marshal.IsComObject(value) && value is IComponent comp) { ISite? site = comp.Site; string? name = site?.Name; if (name != null) { return name; } } // Couldn't find it. return string.Empty; } return s_none; } return base.ConvertTo(context, culture, value, destinationType); } /// <summary> /// Gets a collection of standard values for the reference data type. /// </summary> public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext? context) { List<object?>? components = null; if (context != null) { components = new List<object?> { null }; // Try the reference service first. if (context.GetService(typeof(IReferenceService)) is IReferenceService refSvc) { object[] objs = refSvc.GetReferences(_type); if (objs != null) { for (int i = 0; i < objs.Length; i++) { if (IsValueAllowed(context, objs[i])) { components.Add(objs[i]); } } } } else { // Now try IContainer. IContainer? cont = context.Container; if (cont != null) { ComponentCollection objs = cont.Components; foreach (IComponent obj in objs) { if (obj != null && _type != null && _type.IsInstanceOfType(obj) && IsValueAllowed(context, obj)) { components.Add(obj); } } } } components.Sort(new ReferenceComparer(this)); } return new StandardValuesCollection(components); } /// <summary> /// Gets a value indicating whether the list of standard values returned from /// <see cref='System.ComponentModel.ReferenceConverter.GetStandardValues'/> is an exclusive list. /// </summary> public override bool GetStandardValuesExclusive(ITypeDescriptorContext? context) => true; /// <summary> /// Gets a value indicating whether this object supports a standard set of values /// that can be picked from a list. /// </summary> public override bool GetStandardValuesSupported(ITypeDescriptorContext? context) => true; /// <summary> /// Gets a value indicating whether a particular value can be added to /// the standard values collection. /// </summary> protected virtual bool IsValueAllowed(ITypeDescriptorContext context, object value) => true; /// <summary> /// IComparer object used for sorting references /// </summary> private readonly struct ReferenceComparer : IComparer<object> { private readonly ReferenceConverter _converter; public ReferenceComparer(ReferenceConverter converter) { _converter = converter; } public int Compare(object? item1, object? item2) { string? itemName1 = _converter.ConvertToString(item1); string? itemName2 = _converter.ConvertToString(item2); return string.Compare(itemName1, itemName2, StringComparison.InvariantCulture); } } } }