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);
}
}
}