智能标签(又名 ActionList)在 Visual Studio 中崩溃

发布于 2024-09-07 08:33:46 字数 1190 浏览 3 评论 0原文

将 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 {
[...]

关于如何调试它有什么想法吗?

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();
            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");
    }
}

The DataSource property is declared as such:

    [AttributeProvider(typeof (IListSource))]
    [DefaultValue(null)]
    public object DataSource {
[...]

Any ideas on how to debug it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

执妄 2024-09-14 08:33:46

我找到了解决方案。有必要将包装器属性添加到 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); }
}

等等其他属性。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文