Revit API - 错误的完整类名

问题描述 投票:0回答:6

我对 C# 和编码非常陌生。如果可能的话,我正在寻求一些帮助来弄清楚如何修复这段代码以使其正常工作。

他们单独工作。我可以在功能区上创建一个新按钮并执行标准的 hello world。我还有一个宏,可以在其中成功删除所有工作表和视图,但尝试将两者结合起来会造成很大的困难!代码构建正常,但我在 revit 中收到此错误:

'无法初始化加载项“删除视图”,因为该类 在加载项程序集中找不到“DeleteViews”。FullClassName 为Revit调用附加应用程序提供入口点。为了 Revit 要运行加载项,您必须确保此类实现 “Autodesk.Revit.UI.ExternalCommand”界面。'

我很确定我的问题是在第二段代码中引用的。我知道我没有正确调用它,但一直无法找到任何解决方案。

如果这是一个愚蠢的问题,我深表歉意,但非常感谢任何帮助我学习的帮助!

感谢您给我的任何帮助

代码:

namespace BGPanel
{
public class CsBGPanel : IExternalApplication
{
    public UIDocument ActiveUIDocument { get; private set; }
    public Result OnStartup(UIControlledApplication application)
    {
        RibbonPanel ribbonPanel = application.CreateRibbonPanel("Tools");

        string thisAssemblyPath = Assembly.GetExecutingAssembly().Location;
        PushButtonData buttonData = new PushButtonData("cmdDeleteViews",
           "Delete Views", thisAssemblyPath, "BGPanel.DeleteViews");

        PushButton pushButton = ribbonPanel.AddItem(buttonData) as PushButton;

        pushButton.ToolTip = "Delete all sheets, schedules & views except structural plans";

        Uri uriImage = new Uri(@"C:\Revit_API\Revit_2015\32px-Broom.png");
        BitmapImage largeImage = new BitmapImage(uriImage);
        pushButton.LargeImage = largeImage;

        return Result.Succeeded;
    }

         public void DeleteViews()
    {
        UIDocument uidoc = this.ActiveUIDocument;
        Document doc = uidoc.Document;

        FilteredElementCollector collector = new FilteredElementCollector(doc);
        ICollection<Element> collection = collector.OfClass(typeof(View)).ToElements();

        using (Transaction t = new Transaction(doc, "Delete Views"))
        {
            t.Start();

            int x = 0;

            foreach (Element e in collection)
            {
                try
                {
                    View view = e as View;

                    switch (view.ViewType)
                    {
                        case ViewType.FloorPlan:
                            break;
                        case ViewType.EngineeringPlan:
                            break;
                        case ViewType.ThreeD:
                            break;
                        default:
                            doc.Delete(e.Id);
                            x += 1;
                            break;
                    }
                }
                catch (Exception ex)
                {
                    View view = e as View;
                    TaskDialog.Show("Error", e.Name + "\n" + "\n" + ex.Message);
                    TaskDialog.Show("Error", ex.Message);
                }
            }
            t.Commit();

            TaskDialog.Show("BG_API DeleteViews", "Views Deleted: " + x.ToString());
        }

    }
    public Result OnShutdown(UIControlledApplication application)
    {
        return Result.Succeeded;
    }
}
}
c# revit-api revit revit-2015
6个回答
1
投票

首先,考虑使用反射,而不是自己输入类名:

typeof(YourClassName).FullName

其次,Revit 中的每个命令都需要有自己的类来实现

IExternalCommand
。我没有测试过,但你的代码应该如下所示:

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Windows.Media.Imaging;

using Autodesk.Revit.DB;
using Autodesk.Revit.UI;

namespace BGPanel
{
  public class CsBGPanel : IExternalApplication
  {
    public Result OnStartup(UIControlledApplication application)
    {
      RibbonPanel ribbonPanel = application.CreateRibbonPanel("Tools");

      string thisAssemblyPath = Assembly.GetExecutingAssembly().Location;
      PushButtonData buttonData = new PushButtonData("cmdDeleteViews",
         "Delete Views", thisAssemblyPath, typeof(DeleteViews).FullName);

      PushButton pushButton = ribbonPanel.AddItem(buttonData) as PushButton;

      pushButton.ToolTip = "Delete all sheets, schedules & views except structural plans";

      Uri uriImage = new Uri(@"C:\Revit_API\Revit_2015\32px-Broom.png");
      BitmapImage largeImage = new BitmapImage(uriImage);
      pushButton.LargeImage = largeImage;

      return Result.Succeeded;
    }

    public Result OnShutdown(UIControlledApplication application)
    {
      return Result.Succeeded;
    }
  }

  public class DeleteViews : IExternalCommand
  {
    // this will not work...
    //public UIDocument ActiveUIDocument { get; private set; }

    public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
    {
      UIDocument uidoc = commandData.Application.ActiveUIDocument; //this.ActiveUIDocument;
      Document doc = uidoc.Document;

      FilteredElementCollector collector = new FilteredElementCollector(doc);
      ICollection<Element> collection = collector.OfClass(typeof(View)).ToElements();

      using (Transaction t = new Transaction(doc, "Delete Views"))
      {
        t.Start();

        int x = 0;

        foreach (Element e in collection)
        {
          try
          {
            View view = e as View;

            switch (view.ViewType)
            {
              case ViewType.FloorPlan:
                break;
              case ViewType.EngineeringPlan:
                break;
              case ViewType.ThreeD:
                break;
              default:
                doc.Delete(e.Id);
                x += 1;
                break;
            }
          }
          catch (Exception ex)
          {
            View view = e as View;
            TaskDialog.Show("Error", e.Name + "\n" + "\n" + ex.Message);
            TaskDialog.Show("Error", ex.Message);
          }
        }
        t.Commit();

        TaskDialog.Show("BG_API DeleteViews", "Views Deleted: " + x.ToString());
      }
      return Result.Succeeded; // must return here
    }
  }
}

1
投票

在执行任何其他操作之前,您应该先阅读 Revit API 入门材料,尤其是 DevTV我的第一个 Revit 插件 视频教程:

http://thebuildingcoder.typepad.com/blog/about-the-author.html#2

那么这个问题和许多其他基本问题将得到预先解答,您将为自己和他人节省一些精力和麻烦。


1
投票

由于单击按钮时发生事务错误,我需要在 IExternalCommand 之前添加一行。

[Transaction(TransactionMode.Manual)]

1
投票

我知道这是一篇很旧的文章,但我更喜欢为遇到同样问题的人添加一个答案..

补充一下其他人所说的,验证公共类 CsBGPanel 的名称:IExternalApplication

必须是班级名称

这件事发生在我身上!


0
投票

这个问题的第一个答案建议使用反射“typeof(YourClassName).FullName”当尝试示例代码时,它会返回一个错误,这是可以理解的,因为奥古斯托说他没有测试他的示例。只是为以后的任何人添加...如果您使用“typeof(DeleteViews).FullName”,您需要将其转换为字符串变量,然后他的示例中的代码才能工作。


0
投票

我有一个函数,可以在第二个辅助 DLL 中的功能区栏中创建按钮,因此

string thisAssemblyPath = Assembly.GetExecutingAssembly().Location;
必须更改为
string thisAssemblyPath = Assembly.GetCallingAssembly().Location;
。确保您提供了 DLL 的正确路径,即从 IExternalCommand 派生的类所在的位置。

© www.soinside.com 2019 - 2024. All rights reserved.