我希望有一个“表单”或其他可以添加字符串到列表的内容(无论如何)
将使用包含字符串集合的第一个组件“StringManager
”来完成
另一方面,我希望有另一个组件“ComponentReader
”使用IExtenderProvider并在所有控件(在组件表单上)添加一个名为“TheString”的属性,它允许我从其中一个字符串中选择列表
所以,要明确:我希望与每个表单上的最少代码共享List<String>
,(最多使用属性编辑器)
我不知道怎么能告诉“ComponentReader
”他所指的主要成分在哪里,
(我在“ReferedStringManager
”中添加了一个属性ComponentReader
。
是否有任何属性或指示(或方式)检查项目及其引用以将所有匹配值作为列表中的“ ComponentReader
“属性
对于ReferedStringManager
;
ComponentReader
属性
如果不可能,我会想到静态列表或其他东西,也许是XML文件,(但我不知道如何在构思期间管理它)
当然所有这些都是在设计时,而不是在执行时间(它会更简单!!)
答案 0 :(得分:1)
这是一个迟到的答案,但如果你仍然感兴趣,这里是如何做到的。
对于StringManager和ComponentReader类,有很多要求。
1)两个类都需要从System.ComponentModel.Component派生。
2)StringManager必须覆盖Component类的Site属性。这使它成为“VS Designer aware”,并允许它稍后在ComponentReader的属性中进行选择。
3)StringManager必须将List公开为公共属性。为方便起见,在我的示例代码bolow中,我在VS属性网格中设置了EditorAttribute以便于字符串集合版本。
4)ComponentReader必须实现只有一个StringManager类型属性的自定义接口。这是需求#6所需要的。
5)ComponentReader必须具有StringManager
类型的公共属性6)ComponentReader必须具有SelectedString类型为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; }
}
}
ComponentReader.cs
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:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace VSDesignHost
{
interface IStringManagerEnabled
{
StringManager StringManager
{
get;
set;
}
}
}
StringManagerStringConverter.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);
}
}
}
创建Windows窗体项目,将这些文件添加到其中,然后构建项目。
现在,在Form上,您可以通过从工具箱中拖动来添加每个StringManager和ComponentReader的实例。
选择StringManager,并在属性中,使用字符串集合编辑器向TheList添加一些字符串。
选择ComponentReader,在属性窗口中,您应该能够从下拉列表中选择StringManager实例。
您现在应该可以从SelectedString的下拉列表中选择一个字符串。
我希望你喜欢
吕克