|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.CodeDom;
using System.Windows.Forms;
namespace System.ComponentModel.Design.Serialization;
public abstract partial class CodeDomDesignerLoader
{
/// <summary>
/// This extender provider provides the "Modifiers" property.
/// </summary>
[ProvideProperty("Modifiers", typeof(IComponent))]
[ProvideProperty("GenerateMember", typeof(IComponent))]
private class ModifiersExtenderProvider : IExtenderProvider
{
private IDesignerHost? _host;
/// <summary>
/// Determines if ths extender provider can extend the given object. We extend
/// all objects, so we always return true.
/// </summary>
public bool CanExtend(object o)
{
if (o is not IComponent component)
{
return false;
}
// We don't add modifiers to the base component.
IComponent? baseComponent = GetBaseComponent(component);
if (o == baseComponent)
{
return false;
}
// Now see if this object is inherited. If so, then we don't want to
// extend.
if (!TypeDescriptor.GetAttributes(o)[typeof(InheritanceAttribute)]!.Equals(InheritanceAttribute.NotInherited))
{
return false;
}
return true;
}
private IComponent? GetBaseComponent(IComponent component)
{
_host ??= component.Site?.GetService<IDesignerHost>();
return _host?.RootComponent;
}
/// <summary>
/// This is an extender property that we offer to all components
/// on the form. It implements the "GenerateMember" property, which
/// is a boolean that, if true, causes a field member to be generated for
/// the object.
/// </summary>
[DesignOnly(true)]
[DefaultValue(true)]
[SRDescription(nameof(SR.CodeDomDesignerLoaderPropGenerateMember))]
[Category("Design")]
[HelpKeyword("Designer_GenerateMember")]
public static bool GetGenerateMember(IComponent comp)
{
if (comp.Site.TryGetService(out IDictionaryService? dictionary))
{
if (dictionary.GetValue("GenerateMember") is bool value)
{
return value;
}
}
return true;
}
/// <summary>
/// This is an extender property that we offer to all components
/// on the form. It implements the "Modifiers" property, which
/// is an enum representing the "public/protected/private" scope
/// of a component.
/// </summary>
[DesignOnly(true)]
[TypeConverter(typeof(ModifierConverter))]
[DefaultValue(MemberAttributes.Private)]
[SRDescription(nameof(SR.CodeDomDesignerLoaderPropModifiers))]
[Category("Design")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[HelpKeyword("Designer_Modifiers")]
public static MemberAttributes GetModifiers(IComponent comp)
{
if (comp.Site.TryGetService(out IDictionaryService? dictionary))
{
if (dictionary.GetValue("Modifiers") is MemberAttributes value)
{
return value;
}
}
// Check to see if someone offered up a "DefaultModifiers" property so we can
// decide a default.
if (TypeDescriptorHelper.TryGetPropertyValue(comp, "DefaultModifiers",
out MemberAttributes memberAttributes))
{
return memberAttributes;
}
return MemberAttributes.Private;
}
/// <summary>
/// This is an extender property that we offer to all components
/// on the form. It implements the "GenerateMember" property, which
/// is a boolean that, if true, causes a field member to be generated for
/// the object.
/// </summary>
public static void SetGenerateMember(IComponent comp, bool generate)
{
ISite? site = comp.Site;
if (site is null)
{
return;
}
IDictionaryService? dictionary = site.GetService<IDictionaryService>();
bool oldValue = GetGenerateMember(comp);
dictionary?.SetValue("GenerateMember", generate);
// If the old value was true and the new value is false, we've got
// to remove the existing member declaration for this
// component
if (!oldValue || generate)
{
return;
}
string? compName = site.Name;
CodeTypeDeclaration? typeDecl = site.GetService<CodeTypeDeclaration>();
if (typeDecl is null || compName is null)
{
return;
}
foreach (CodeTypeMember member in typeDecl.Members)
{
if (member is CodeMemberField field && field.Name.Equals(compName))
{
typeDecl.Members.Remove(field);
break;
}
}
}
/// <summary>
/// This is an extender property that we offer to all components
/// on the form. It implements the "Modifiers" property, which
/// is an enum representing the "public/protected/private" scope
/// of a component.
/// </summary>
public static void SetModifiers(IComponent comp, MemberAttributes modifiers)
{
if (comp.Site.TryGetService(out IDictionaryService? dictionary))
{
dictionary.SetValue("Modifiers", modifiers);
}
}
}
}
|