检查System.Windows.Forms.Design.StringCollectionEditor中是否有更改,以触发C#Winforms中的propertyGrid PropertyValue更改事件
我有一个带有字符串集合编辑器的用户控件,在其中保存选项卡页面名称列表,如下所示:检查System.Windows.Forms.Design.StringCollectionEditor中是否有更改,以触发C#Winforms中的propertyGrid PropertyValue更改事件,c#,winforms,tabs,user-controls,propertygrid,C#,Winforms,Tabs,User Controls,Propertygrid,我有一个带有字符串集合编辑器的用户控件,在其中保存选项卡页面名称列表,如下所示: [Editor(@"System.Windows.Forms.Design.StringCollectionEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(System.Drawing.Design.UITypeEditor))] public List
[Editor(@"System.Windows.Forms.Design.StringCollectionEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(System.Drawing.Design.UITypeEditor))]
public List<string> TabPages {
get {return tabpages;}
set {
tabpages = value;
}
}
在职能范围内:
private void propertyGrid1_PropertyValueChanged(object s, PropertyValueChangedEventArgs e);
与我的财产相关联的,如下所示:
this.propertyGrid1.PropertyValueChanged += new System.Windows.Forms.PropertyValueChangedEventHandler(this.propertyGrid1_PropertyValueChanged);
但是,对于collection,StringCollectionEditor中的更改不会在此过程中检测到
是否有一个与我需要订阅的StringCollectionEditor关联的特殊事件处理程序?或者也许有什么办法可以让我改变声明
如果在这方面有任何帮助,我将不胜感激
[已编辑]
我的约束:
一种可能是拦截
StringCollectionEditor
,为此,您必须创建如下自定义编辑器:
class MyEditor : UITypeEditor
{
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.Modal;
}
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
var type = Type.GetType(@"System.Windows.Forms.Design.StringCollectionEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
dynamic editor = Activator.CreateInstance(type, new[] { typeof(UITypeEditor) });
var result = editor.EditValue(context, provider, value);
// call your event here
return result;
}
}
像这样使用它
[Editor(typeof(MyEditor), typeof(UITypeEditor))]
public List<string> TabPages { get; } = new List<string>();
我无法将
Microsoft.Csharp
添加到我的项目中,因为它是.net3.5
项目
最后,我们必须坚持在不使用dynamic
关键字的情况下更改代码,如下所示:
class MyEditor : UITypeEditor {
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) {
return UITypeEditorEditStyle.Modal;
}
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) {
var type = Type.GetType(@"System.Windows.Forms.Design.StringCollectionEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
var editor = Activator.CreateInstance(type, new[] { typeof(UITypeEditor) });
var result = ((UITypeEditor)editor).EditValue(context, provider, value);
// call your event here
return result;
}
}
我相信下面的代码之所以有效是因为Liskov取代基原理。但我不完全清楚。我发现,您可以尝试使用observable集合(然后您将拥有事件),或者您可以始终创建自定义编辑器。至于
PropertyValueChanged
它之所以没有被触发,是因为您没有更改该属性的值(PropertyGrid
允许您编辑getter-only属性)。我无法将其更改为observable colleciton在我的情况下,它只是一个字符串列表,稍后我会在运行时将它自己的属性与之关联。不确定是否能够及时创建自定义编辑器:(关闭StringCollectionEditor后是否触发任何事件?我正在寻找一种机制,该机制可以从外部触发PropertyGrid的PropertyValue更改事件行var result=Editor.EditValue(上下文、提供程序、值);
给出错误消息“预定义类型‘Microsoft.CSharp.RuntimeBinder.Binder’未定义或导入”,因为我正在使用VS 2010和.net 3.5。需要您的帮助来进一步推动它。是因为动态的原因吗?我使用它是为了避免显式使用反射来调用EditValue()
method with parameters,请参阅。坦率地说,我对C#还是个新手,不知道反射是什么。让我看看你的建议是否有助于解决问题。谢谢。
readonly List<string> _tagPages = new List<string>();
[Editor(typeof(MyEditor), typeof(UITypeEditor))]
public List<string> TabPages { get { return _tabPages; } }
// reflection part
var type = Type.GetType(@"System.Windows.Forms.Design.StringCollectionEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
var editor = Activator.CreateInstance(type, new[] { typeof(UITypeEditor) });
var method = type.GetMethod(nameof(EditValue), new[] { typeof(ITypeDescriptorContext), typeof(IServiceProvider), typeof(object) }); // if nameof is also missing then just use "EditValue" in place of it
var result = method.Invoke(editor, new[] { context, provider, value });
class MyEditor : UITypeEditor {
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) {
return UITypeEditorEditStyle.Modal;
}
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) {
var type = Type.GetType(@"System.Windows.Forms.Design.StringCollectionEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
var editor = Activator.CreateInstance(type, new[] { typeof(UITypeEditor) });
var result = ((UITypeEditor)editor).EditValue(context, provider, value);
// call your event here
return result;
}
}