1 //------------------------------------------------------------------------------
2 // <copyright file="ReferenceConverter.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 //------------------------------------------------------------------------------
9 namespace System.ComponentModel {
10 using Microsoft.Win32;
11 using System.Collections;
12 using System.ComponentModel.Design;
13 using System.Diagnostics;
14 using System.Globalization;
15 using System.Runtime.InteropServices;
16 using System.Runtime.Remoting;
17 using System.Runtime.Serialization.Formatters;
18 using System.Security.Permissions;
21 /// <para>Provides a type converter to convert object references to and from various
22 /// other representations.</para>
24 [HostProtection(SharedState = true)]
25 public class ReferenceConverter : TypeConverter {
27 private static readonly string none = SR.GetString(SR.toStringNone);
32 /// Initializes a new instance of the <see cref='System.ComponentModel.ReferenceConverter'/> class.
35 public ReferenceConverter(Type type) {
41 /// <para>Gets a value indicating whether this converter can convert an object in the
42 /// given source type to a reference object using the specified context.</para>
44 public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) {
45 if (sourceType == typeof(string) && context != null) {
48 return base.CanConvertFrom(context, sourceType);
53 /// <para>Converts the given object to the reference type.</para>
55 public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) {
57 if (value is string) {
58 string text = ((string)value).Trim();
60 if (!String.Equals(text, none) && context != null) {
62 // Try the reference service first.
64 IReferenceService refSvc = (IReferenceService)context.GetService(typeof(IReferenceService));
66 object obj = refSvc.GetReference(text);
74 IContainer cont = context.Container;
76 object obj = cont.Components[text];
85 return base.ConvertFrom(context, culture, value);
90 /// <para>Converts the given value object to the reference type
91 /// using the specified context and arguments.</para>
93 public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) {
94 if (destinationType == null) {
95 throw new ArgumentNullException("destinationType");
98 if (destinationType == typeof(string)) {
101 // Try the reference service first.
103 if (context != null) {
104 IReferenceService refSvc = (IReferenceService)context.GetService(typeof(IReferenceService));
105 if (refSvc != null) {
106 string name = refSvc.GetName(value);
113 // Now see if this is an IComponent.
115 if (!Marshal.IsComObject(value) && value is IComponent) {
116 IComponent comp = (IComponent)value;
117 ISite site = comp.Site;
119 string name = site.Name;
132 return base.ConvertTo(context, culture, value, destinationType);
137 /// <para>Gets a collection of standard values for the reference data type.</para>
139 public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) {
141 object[] components = null;
143 if (context != null) {
144 ArrayList list = new ArrayList();
147 // Try the reference service first.
149 IReferenceService refSvc = (IReferenceService)context.GetService(typeof(IReferenceService));
150 if (refSvc != null) {
151 object[] objs = refSvc.GetReferences(type);
152 int count = objs.Length;
154 for (int i = 0; i < count; i++) {
155 if (IsValueAllowed(context, objs[i]))
161 // Now try IContainer.
163 IContainer cont = context.Container;
165 ComponentCollection objs = cont.Components;
167 foreach(IComponent obj in objs) {
168 if (obj != null && type.IsInstanceOfType(obj) &&
169 IsValueAllowed(context, obj)) {
176 components = list.ToArray();
177 Array.Sort(components, 0, components.Length, new ReferenceComparer(this));
180 return new StandardValuesCollection(components);
185 /// <para>Gets a value indicating whether the list of standard values returned from
186 /// <see cref='System.ComponentModel.ReferenceConverter.GetStandardValues'/> is an exclusive list. </para>
188 public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) {
194 /// <para>Gets a value indicating whether this object supports a standard set of values
195 /// that can be picked from a list.</para>
197 public override bool GetStandardValuesSupported(ITypeDescriptorContext context) {
202 /// <para>Gets a value indicating whether a particular value can be added to
203 /// the standard values collection.</para>
205 protected virtual bool IsValueAllowed(ITypeDescriptorContext context, object value) {
210 /// IComparer object used for sorting references
212 private class ReferenceComparer : IComparer {
214 private ReferenceConverter converter;
216 public ReferenceComparer(ReferenceConverter converter) {
217 this.converter = converter;
220 public int Compare(object item1, object item2) {
222 String itemName1 = converter.ConvertToString(item1);
223 String itemName2 = converter.ConvertToString(item2);
225 return string.Compare(itemName1, itemName2, false, CultureInfo.InvariantCulture);