smart tags (aka ActionList) crash in visual studio
Adding smart tags in VS2010 (or VS2008 for that matter) to my control makes VS crash.
The following designer is used for the action list:
internal class DataEditorDesigner : ComponentDesigner {
[...]
public override DesignerActionListCollection ActionLists {
get {
var lists = new DesignerActionListCollection();
lis开发者_C百科ts.AddRange(base.ActionLists);
lists.Add(new DataEditorActionList(Component));
return lists;
}
}
}
internal class DataEditorActionList : DesignerActionList {
public DataEditorActionList(IComponent component) : base(component) {}
public override DesignerActionItemCollection GetSortedActionItems() {
var items = new DesignerActionItemCollection();
items.Add(new DesignerActionPropertyItem("DataSource", "Data Source:", "Data"));
items.Add(new DesignerActionMethodItem(this, "AddControl", "Add column..."));
return items;
}
private void AddControl() {
System.Windows.Forms.MessageBox.Show("dpa");
}
}
The DataSource property is declared as such:
[AttributeProvider(typeof (IListSource))]
[DefaultValue(null)]
public object DataSource {
[...]
Any ideas on how to debug it?
I've found the solution. It's necessary to add wrapper properties to DesignerActionList classes, that's where they're read from, not from the actual component. Also, it's necessary to write such code:
internal static PropertyDescriptor GetPropertyDescriptor(IComponent component, string propertyName) {
return TypeDescriptor.GetProperties(component)[propertyName];
}
internal static IDesignerHost GetDesignerHost(IComponent component) {
return (IDesignerHost) component.Site.GetService(typeof (IDesignerHost));
}
internal static IComponentChangeService GetChangeService(IComponent component) {
return (IComponentChangeService) component.Site.GetService(typeof (IComponentChangeService));
}
internal static void SetValue(IComponent component, string propertyName, object value) {
PropertyDescriptor propertyDescriptor = GetPropertyDescriptor(component, propertyName);
IComponentChangeService svc = GetChangeService(component);
IDesignerHost host = GetDesignerHost(component);
DesignerTransaction txn = host.CreateTransaction();
try {
svc.OnComponentChanging(component, propertyDescriptor);
propertyDescriptor.SetValue(component, value);
svc.OnComponentChanged(component, propertyDescriptor, null, null);
txn.Commit();
txn = null;
} finally {
if (txn != null)
txn.Cancel();
}
}
and then use it:
[AttributeProvider(typeof (IListSource))]
public object DataSource {
get { return Editor.DataSource; }
set { DesignerUtil.SetValue(Component, "DataSource", value); }
}
and so on for other properties.
精彩评论