Сбой смарт-тегов (aka ActionList) в визуальной студии
Добавление смарт-тегов в VS2010 (или VS2008 в этом отношении) в мой элемент управления приводит к сбою VS.
Следующий список используется для списка действий:
internal class DataEditorDesigner : ComponentDesigner {
[...]
public override DesignerActionListCollection ActionLists {
get {
var lists = new DesignerActionListCollection();
lists.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");
}
}
Свойство DataSource объявлено так:
[AttributeProvider(typeof (IListSource))]
[DefaultValue(null)]
public object DataSource {
[...]
Любые идеи о том, как его отладить?
1 ответ
Решение
Я нашел решение. Необходимо добавить свойства оболочки в классы DesignerActionList, откуда они читаются, а не из фактического компонента. Также необходимо написать такой код:
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();
}
}
и затем используйте это:
[AttributeProvider(typeof (IListSource))]
public object DataSource {
get { return Editor.DataSource; }
set { DesignerUtil.SetValue(Component, "DataSource", value); }
}
и так далее для других свойств.