我有一个可以通过PropertyGrid
编辑的自定义类。在该课程中,我有一个自定义Collection
(自定义PropertyDescriptor
和TypeConverter
)。
可以使用默认的Collection Editor在Collection
中添加或删除项目。一切正常。但是 - 关闭集合编辑器后,PropertyGrid不会更新。当我手动拨打Refresh()
上的PropertyGrid
时,更改会反映在PropertyGrid中。
如何在关闭集合编辑器时让PropertyGrid自动刷新?我之前寻求一个解决方案,我应该将CollectionEditor子类化(我似乎无法找到)。
请帮忙。
答案 0 :(得分:1)
RefreshPropertiesAttribute类
表示属性网格 应该在关联时刷新 财产价值变化。这个班 不能继承。
从http://msdn.microsoft.com/en-us/library/system.componentmodel.refreshpropertiesattribute.aspx
插入 Public Overrides ReadOnly Property Attributes() As System.ComponentModel.AttributeCollection
Get
Return New AttributeCollection(New Attribute() {RefreshPropertiesAttribute.Repaint})
End Get
End Property
演练:在设计时调试自定义Windows窗体控件 http://msdn.microsoft.com/en-us/library/5ytx0z24.aspx
答案 1 :(得分:1)
您也可以尝试将NotifyParentProperty属性添加到集合中。这在类似的情况下对我有用。
答案 2 :(得分:1)
我在这种情况下得到解决方案。 需要派生自CollectionEditor类并制作如下自定义编辑器:
public class MeasuredParamEditor : CollectionEditor
{
public static EventHandler CollectionChanged;
public MeasuredParamEditor(Type type)
: base(type)
{ }
protected override string GetDisplayText(object value)
{
if (value is MeasuredParam)
{
MeasuredParam param = (MeasuredParam)value;
return string.Format("{0}: {1}", param.Name, param.Value);
}
else return base.GetDisplayText(value);
}
protected override CollectionForm CreateCollectionForm()
{
CollectionForm collectionForm = base.CreateCollectionForm();
Form frm = collectionForm as Form;
if (frm != null)
{
// Get OK button of the Collection Editor...
Button button = frm.AcceptButton as Button;
// Handle click event of the button
button.Click += new EventHandler(OnCollectionChanged);
}
return collectionForm;
}
void OnCollectionChanged(object sender, EventArgs e)
{
if (CollectionChanged != null)
{
CollectionChanged(sender, e);
}
}
}
在主窗体中,我订阅了自定义编辑器的静态事件。
private void MainForm_Load(object sender, EventArgs e)
{
MeasuredParamEditor.CollectionChanged += new EventHandler(OnMeasuredParamsChanged);
}
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
MeasuredParamEditor.CollectionChanged -= new EventHandler(OnMeasuredParamsChanged);
}
void OnMeasuredParamsChanged(object sender, EventArgs e)
{
this.myPropGrid.Refresh();
}
问候,Artem
答案 3 :(得分:1)
我使用这个基类
public class CollectionEditorBase : CollectionEditor
{
protected PropertyGrid ownerGrid;
public CollectionEditorBase(Type type) : base(type) { }
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
PropertyInfo ownerGridProperty = provider.GetType().GetProperty("OwnerGrid", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
ownerGrid = (PropertyGrid)ownerGridProperty.GetValue(provider);
return base.EditValue(context, provider, value);
}
protected override CollectionForm CreateCollectionForm()
{
CollectionForm cf = base.CreateCollectionForm();
cf.FormClosing += delegate(object sender, FormClosingEventArgs e)
{
ownerGrid.Refresh();
if (CollectionEditorClosed != null)
CollectionEditorClosed(this, value);
};
return cf;
}
}
然后你只需将你的收藏编辑器作为基础。收集表单关闭时,它将自动刷新属性网格。
请注意,这个解决方案反映在属性网格的内部,可以随时打破,但我已经做了一段时间了,没有问题
答案 4 :(得分:0)
完美解决方案
using System;
using System.ComponentModel.Design;
using System.Windows.Forms;
using System.Drawing.Design;
using System.Collections;
using System.ComponentModel;
namespace ppgExpandableList
{
public class ExpandableListEditor : CollectionEditor
{
public ExpandableListEditor(Type type) : base(type){}
public override object EditValue(ITypeDescriptorContext context,
System.IServiceProvider provider, object value)
{
object editedValue = base.EditValue(context, provider, value);
IList tmpList = (IList)editedValue;
object tmpValue = Activator.CreateInstance(value.GetType());
IList editedList = (IList)tmpValue;
foreach (object item in tmpList)
{
editedList.Add(item);
}
return editedList;
}
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.Modal;
}
}
}