2

I'm very new to C# and coding. If possible I'm after some assistance figuring out how to fix this piece of code up to work.

They work individually. I can create a new button on the ribbon and execute the standard hello world. i also have a macro which works where I can remove all my sheets and views successfully but trying to combine the two is causing big difficulties! The code builds OK but I'm getting this error inside revit:

'Failed to initialize the add-in "Delete Views" because the class "DeleteViews" cannot be found in the add-in assembly.The FullClassName provides the enrty point for Revit to call add-in application. For Revit to run the add-in, you must ensure this class implements the "Autodesk.Revit.UI.ExternalCommand" interface.'

I'm pretty sure my problem is referencing in this 2nd bit of code. i know I'm not calling it up correctly but haven't been able to find any solutions.

Apologies if this is a dumb question but would really appreciate any help to help me learn!

Thanks for any help you can give me

The code:

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;
    }
}
}
lokusking
  • 7,396
  • 13
  • 38
  • 57
Shaps
  • 21
  • 2

5 Answers5

1

First, instead typing the class name yourself, consider using Reflection like:

typeof(YourClassName).FullName

Second, every command in Revit requires its own class that implements IExternalCommand. I haven't tested, but your code should be something like the following:

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
    }
  }
}
Augusto Goncalves
  • 8,493
  • 2
  • 17
  • 44
1

You should work through the Revit API getting started material before doing anything else at all, especially the DevTV and My First Revit Plugin video tutorials:

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

Then this question and many other fundamental issues will be answered up front, and you will save yourself and others some effort and head-scratching.

Jeremy Tammik
  • 7,333
  • 2
  • 12
  • 17
1

I needed to add a line before the IExternalCommand because of transaction errors when I clicked my button.

[Transaction(TransactionMode.Manual)]
geisterfurz007
  • 5,292
  • 5
  • 33
  • 54
Rory
  • 159
  • 1
  • 8
1

I know it is so old article but I prefere to add an answer for whom will get the same probleme..

En addition of what others said, verfiy the name of public class CsBGPanel : IExternalApplication

It must be as the name of class

It happend to me!

AAGFX
  • 11
  • 1
0

The first answer to this question suggests using the reflection "typeof(YourClassName).FullName" When the sample code is tried it returns a error, understandably as Augusto says he did not test his example. Just adding for anyone down the road... If you use "typeof(DeleteViews).FullName" you would need to cast it into a string variable before the code in his example would work.

Brandon
  • 1
  • 2
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Aug 12 '22 at 08:09
  • This does not provide an answer to the question. Once you have sufficient [reputation](https://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](https://stackoverflow.com/help/privileges/comment); instead, [provide answers that don't require clarification from the asker](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). - [From Review](/review/late-answers/32438474) – lee-m Aug 15 '22 at 09:34
  • This clarifies an existing answer, to be more precise it makes the other answer work whereas it currently does not work. This question has three other replies, one by the OP. The first answer suggested using "typeof(YourClassName).FullName", I added a comment to clarify and make that code work. Its not that hard to follow really and you recommending deletion only hurts the next guy who attempts to solve his problem by reading the above. – Brandon Aug 16 '22 at 13:32
  • As I learn more about stackoverflow I understand now what you mean now "lee-m", thank you . However since I cannot yet comment I have no other recourse. Its kind of a catch22. I will circle back to delete this comment but wanted to tell you I understand you now. – Brandon Apr 05 '23 at 19:19