首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >设计时的组件通信

设计时的组件通信
EN

Stack Overflow用户
提问于 2011-04-22 10:39:46
回答 1查看 403关注 0票数 1

我希望有一个“表单”或者其他什么东西(不管是什么),可以将字符串添加到列表中。

它将使用包含字符串集合的第一个组件"StringManager“来完成。

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

因此,为了清楚起见:我希望共享每个表单上的代码最少的List<String> (大多数使用属性编辑器)。

我不知道我怎么能告诉"ComponentReader“他所指的主要成分在哪里,

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

是否有任何属性或指令(或方式)来检查项目和他的引用以获得ComponentReaderReferedStringManager属性的"ComponentReader“属性中所有可匹配的值;

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

当然,所有这些都是在设计时,而不是在执行时(这将是如此简单!)

EN

回答 1

Stack Overflow用户

发布于 2011-08-15 01:23:26

这是一个迟来的答案,但如果你仍然感兴趣,下面是如何做到这一点。

StringManager和ComponentReader类都有相当多的需求。

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

2) StringManager必须覆盖组件类的Site属性。这就是让它"VS Designer感知“的原因,并允许以后在ComponentReader的属性中选择它。

3) StringManager必须将列表公开为公共属性。为了方便起见,在我的示例代码bolow中,我在VS属性网格中设置了易于字符串收集版本的EditorAttribute。

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

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

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

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

现在,对于代码:

StringManager.cs

代码语言:javascript
复制
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; }

}
}

ComponentReader.cs

代码语言:javascript
复制
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

namespace VSDesignHost
{
    class ComponentReader : Component, IStringManagerEnabled
    {
        private StringManager sm;

        public ComponentReader()
        {
            sm = null;
        }

        [Browsable(true), Category("MyCategory")]
        public StringManager StringManager
        {
            get { return sm; }
            set
            {
                sm = value;
            }
        }

        [Browsable(true), Category("MyCategory"), TypeConverter(typeof(StringManagerStringConverter))]
        public string SelectedString { get; set; }

    }
}

IStringManagerEnabled.cs:

代码语言:javascript
复制
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace VSDesignHost
{
    interface IStringManagerEnabled
    {
        StringManager StringManager
        {
            get;
            set;
        }
    }
}

StringManagerStringConverter.cs:

代码语言:javascript
复制
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);
        }

    }
}

创建一个Windows窗体项目,将这些文件添加到其中,然后生成该项目。

现在,在表单上,可以从工具箱中拖动每个StringManager和ComponentReader的实例。

选择StringManager,并在属性中使用string集合编辑器向TheList添加几个字符串。

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

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

我希望你喜欢

Luc

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5754589

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档