Revit API - неправильное полное имя класса

Я очень плохо знаком с C# и кодированием. Если возможно, я после некоторой помощи выясню, как исправить этот кусок кода для работы.

Они работают индивидуально. Я могу создать новую кнопку на ленте и выполнить стандартный привет мир. у меня также есть макрос, который работает, где я могу успешно удалить все свои листы и представления, но попытка объединить их вызывает большие трудности! Код строится нормально, но я получаю эту ошибку внутри revit:

"Не удалось инициализировать надстройку"Delete Views", так как класс" 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;
    }
}
}

6 ответов

Во-первых, вместо того, чтобы вводить имя класса самостоятельно, рассмотрите возможность использования Reflection следующим образом:

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
    }
  }
}

Мне нужно было добавить строку перед IExternalCommand из-за ошибок транзакции, когда я нажимал кнопку.

[Transaction(TransactionMode.Manual)]

Прежде чем делать что-либо еще, особенно видео-уроки по DevTV и My First Revit Plugin, вы должны изучить материал для начала работы с Revit API:

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

Тогда на этот вопрос и многие другие фундаментальные вопросы будут даны ответы заранее, и вы сэкономите себе и другим некоторые усилия и царапины на голове.

Я знаю, что это очень старая статья, но я предпочитаю добавить ответ для тех, у кого возникнет такая же проблема.

В дополнение к тому, что сказали другие, проверьте имя открытого класса CsBGPanel: IExternalApplication.

Это должно быть имя класса

Это случилось со мной!

Первый ответ на этот вопрос предполагает использование отражения "typeof(YourClassName).FullName". Когда код примера пробуется, он возвращает ошибку, что понятно, поскольку Аугусто говорит, что не тестировал свой пример. Просто добавьте для тех, кто в будущем... Если вы используете "typeof(DeleteViews).FullName", вам нужно будет преобразовать его в строковую переменную, прежде чем код в его примере сработает.

У меня была функция, которая создает кнопку на ленточной панели во второй вспомогательной DLL, поэтомупришлось изменить на. Убедитесь, что вы указали правильный путь к DLL, в которой находится ваш класс, производный от IExternalCommand.

Другие вопросы по тегам