C# 设计时的组件通信

C# 设计时的组件通信,c#,winforms,C#,Winforms,我希望有一个“表单”或其他东西(无论什么)可以将字符串添加到列表中 这将通过包含字符串集合的第一个组件“StringManager”完成 另一方面,我希望有另一个组件“ComponentReader”,它使用IExtenderProvider并在所有控件(在组件窗体上)上添加一个名为“TheString”的属性,让我从列表中选择一个字符串 因此,需要明确的是:我想共享列表,每个表单上的代码最少(属性编辑器中的代码最多) 我不知道如何才能告诉“ComponentReader”他提到的主要组件在哪里

我希望有一个“表单”或其他东西(无论什么)可以将字符串添加到列表中

这将通过包含字符串集合的第一个组件“
StringManager
”完成

另一方面,我希望有另一个组件“
ComponentReader
”,它使用IExtenderProvider并在所有控件(在组件窗体上)上添加一个名为“TheString”的属性,让我从列表中选择一个字符串

因此,需要明确的是:我想共享
列表
,每个表单上的代码最少(属性编辑器中的代码最多)

我不知道如何才能告诉“
ComponentReader
”他提到的主要组件在哪里

(我已经在我的“
ComponentReader
”中添加了一个属性
ReferedStringManager

是否有任何属性或说明(或方法)来检查项目及其参考,以获得“
ComponentReader
”属性中列出的所有匹配值 对于
ComponentReader
ReferedStringManager
属性

如果不可能,我会想到静态列表或其他东西,可能是XML文件(但我不知道在构思过程中如何管理它)


当然,所有这些都是在设计时进行的,而不是在执行时进行的(这样会更简单!!)

这是一个迟来的答案,但是如果您仍然感兴趣,下面介绍如何进行

StringManager和ComponentReader类都有很多要求

1) 这两个类都需要从System.ComponentModel.Component派生

2) StringManager必须重写组件类的Site属性。这就是它“VS Designer aware”的原因,并允许以后在ComponentReader的属性中选择它

3) StringManager必须将列表公开为公共属性。为了方便起见,在我的示例代码bolow中,我在VS属性网格中为easy string collection edition设置了EditorAttribute

4) ComponentReader必须实现只有一个StringManager类型属性的自定义接口。这是需求6所需要的

5) ComponentReader必须具有StringManager类型的公共属性

6) 对于SelectedString,ComponentReader必须具有string类型的公共属性。问题是我们必须将TypeConverterAttribute设置为另一个必须实现的类(参见#7)

7) 我们必须实现一个StringConverter派生类。这将用于允许我们从选定的StringManager中选择字符串。在这个类中,我们必须能够通过在#4中创建的接口检索对ComponentReader的引用

现在,对于代码:

StringManager.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Windows.Forms;
using System.ComponentModel.Design;

namespace VSDesignHost
{
class StringManager : Component
{
    private ContainerControl _containerControl = null;

    public StringManager()
    {
        TheList = new List<string>();
    }

    public StringManager(IContainer container) : this()
    {
        container.Add(this);

        InitializeComponent();
    }

    private void InitializeComponent()
    {
        //Whatever
    }

    public ContainerControl ContainerControl
    {
        get { return _containerControl; }
        set { _containerControl = value; }
    }

    public override ISite Site
    {
        set
        {
            base.Site = value;
            if (value != null)
            {
                IDesignerHost host = value.GetService(typeof(IDesignerHost)) as IDesignerHost;
                if (host != null)
                {
                    IComponent rootComponent = host.RootComponent;
                    if (rootComponent is ContainerControl)
                    {
                        this.ContainerControl = (ContainerControl)rootComponent;
                    }
                }
            }
        }
    }

    [Editor("System.Windows.Forms.Design.StringCollectionEditor, System.Design", "System.Drawing.Design.UITypeEditor, System.Drawing")]
    public List<string> TheList { get; set; }

}
}
IStringManagerEnabled.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace VSDesignHost
{
    interface IStringManagerEnabled
    {
        StringManager StringManager
        {
            get;
            set;
        }
    }
}
StringManager StringConverter.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

namespace VSDesignHost
{
    class StringManagerStringConverter : StringConverter
    {
        #region Make It A ComboBox
        public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
        {
            return true;
        }
        public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
        {
            return false;
        }
        #endregion


        #region Display Tags In List
        public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
        {
            if ((context == null) || (context.Container == null))
            {
                return null;
            }

            Object[] Tags = this.GetTagsFromServer(context);
            if (Tags != null)
            {
                return new StandardValuesCollection(Tags);
            }
            return null;
        }

        private object[] GetTagsFromServer(ITypeDescriptorContext context)
        {
            List<string> availableTags = new List<string>();

            if (context.Instance == null)
            {
                availableTags.Add("ITypeDescriptorContext.Instance is null");
                return availableTags.ToArray();
            }


            IStringManagerEnabled inst = context.Instance as IStringManagerEnabled;
            if (inst == null)
            {
                availableTags.Add(context.Instance.ToString());
                return availableTags.ToArray();
            }

            if (inst.StringManager == null)
            {
                availableTags.Add("No StringManager selected");
                return availableTags.ToArray();
            }

            availableTags = inst.StringManager.TheList;
            availableTags.Sort(Comparer<string>.Default);
            return availableTags.ToArray();
        }

        #endregion



        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            if (sourceType == typeof(string))
                return true;
            return base.CanConvertFrom(context, sourceType);
        }

        public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
        {
            if (value is string)
                return value.ToString();
            return base.ConvertFrom(context, culture, value);
        }

    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用系统组件模型;
命名空间VSDesignHost
{
类StringManager StringConverter:StringConverter
{
#区域使其成为一个组合框
公共覆盖布尔GetStandardValuesSupported(ITypeDescriptorContext上下文)
{
返回true;
}
public override bool GetStandardValuesExclusive(ITypeDescriptor上下文)
{
返回false;
}
#端区
#区域显示列表中的标记
公共覆盖标准值集合GetStandardValues(ITypeDescriptor上下文)
{
if((context==null)| |(context.Container==null))
{
返回null;
}
Object[]Tags=this.GetTagsFromServer(上下文);
if(标记!=null)
{
返回新的标准值集合(标签);
}
返回null;
}
私有对象[]GetTagsFromServer(ITypeDescriptorContext上下文)
{
List availableTags=新列表();
if(context.Instance==null)
{
availableTags.Add(“ITypeDescriptorContext.Instance为null”);
返回可用的tags.ToArray();
}
IStringManagerEnabled inst=context.Instance作为IStringManagerEnabled;
如果(inst==null)
{
Add(context.Instance.ToString());
返回可用的tags.ToArray();
}
如果(inst.StringManager==null)
{
availableTags.Add(“未选择StringManager”);
返回可用的tags.ToArray();
}
availableTags=inst.StringManager.TheList;
availableTags.Sort(Comparer.Default);
返回可用的tags.ToArray();
}
#端区
公共覆盖布尔CanConvertFrom(ITypeScriptorContext上下文,类型sourceType)
{
if(sourceType==typeof(string))
返回true;
返回base.CanConvertFrom(上下文,sourceType);
}
公共重写对象ConvertFrom(ITypeDescriptorContext上下文,System.Globalization.CultureInfo区域性,对象值)
{
if(值为字符串)
返回值.ToString();
返回base.ConvertFrom(上下文、区域性、值);
}
}
}
创建Windows窗体项目,将这些文件添加到其中,然后生成该项目

现在,在表单上,可以通过从工具箱中拖动来添加StringManager和ComponentReader的每个实例

选择StringManager,然后在属性中,使用字符串集合编辑器向列表中添加一些字符串

选择ComponentReader,在属性窗口中,您应该能够从下拉列表中选择StringManager实例

您现在应该能够从SelectedString的下拉列表中选择一个字符串

我希望你喜欢

土地使用权
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

namespace VSDesignHost
{
    class StringManagerStringConverter : StringConverter
    {
        #region Make It A ComboBox
        public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
        {
            return true;
        }
        public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
        {
            return false;
        }
        #endregion


        #region Display Tags In List
        public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
        {
            if ((context == null) || (context.Container == null))
            {
                return null;
            }

            Object[] Tags = this.GetTagsFromServer(context);
            if (Tags != null)
            {
                return new StandardValuesCollection(Tags);
            }
            return null;
        }

        private object[] GetTagsFromServer(ITypeDescriptorContext context)
        {
            List<string> availableTags = new List<string>();

            if (context.Instance == null)
            {
                availableTags.Add("ITypeDescriptorContext.Instance is null");
                return availableTags.ToArray();
            }


            IStringManagerEnabled inst = context.Instance as IStringManagerEnabled;
            if (inst == null)
            {
                availableTags.Add(context.Instance.ToString());
                return availableTags.ToArray();
            }

            if (inst.StringManager == null)
            {
                availableTags.Add("No StringManager selected");
                return availableTags.ToArray();
            }

            availableTags = inst.StringManager.TheList;
            availableTags.Sort(Comparer<string>.Default);
            return availableTags.ToArray();
        }

        #endregion



        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            if (sourceType == typeof(string))
                return true;
            return base.CanConvertFrom(context, sourceType);
        }

        public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
        {
            if (value is string)
                return value.ToString();
            return base.ConvertFrom(context, culture, value);
        }

    }
}