Oscillating Hexagons with Image-O-Matic

Here is what the folks at caad.arch.rwth-aachen.de got when they combined context aware panels (http://buildz.blogspot.de/2013/01/ori…) and a bit of math (http://au.autodesk.com/?nd=class&…) and documented it with Image-O-Matic

Move improvements to the Keyboard Shortcut Tutor

Another set of improvements have been made to the Keyboard Shortcut Tutor. It now:

  • Works with ribbon buttons that contain drop-down lists such as Wall and Roof
  • Works with sketch commands (Line, Rectangle, Circle, etc.)
  • Shows the shortcut reminder immediately after most commands are invoked
  • Gives focus to the Revit window after showing the reminder

You can download this version at https://boostyourbim.wordpress.com/products/#KeyboardTutor

‘Family Security Guard’ app now available for download

 

2012 Install 2013 Install Use free with the password “boost” or purchase license for $2.99

The user will be prompted for a password in two situations:

  1. In the project environment when they attempt to open the Family Types dialog
  2. When they attempt to open a family file

You can control if you want this check enabled for all Revit family files or not as follows:

  1. The password will be required to edit and open all family files if there is “AlwaysRequirePassword.txt” file in the BoostYourBIM-FamilySecurity.bundle\Contents folder.
  2. If this file does not exist, the password will only be required for families that contain an integer parameter named “AccessRestricted” with a value of 1 (or Yes, if you choose to make it a Yes/No parameter)

After the password is successfully entered, the user will not be prompted again for the password during that Revit session. If you purchase a license, a custom password can be set in the pwd.txt file in the BoostYourBIM-FamilySecurity.bundle\Contents folder.

NOTE: This app only protects families when this app is installed. There is no protection when someone without this app attempts to modify families.

Deadline extended for the Image-O-Matic contest

little_bird_told_meThis little bird told me that there are some crazy awesome things being done out there in the BIM-o-sphere with Revit and Image-O-Matic.

So I’m extending the deadline for the custom-built Revit API app until March 15. I look forward to seeing what you’re up to!

‘Move Physical to Analytical’ app now available

Here’s something especially for all you Revit Structure fans…

This free app is now available at the Autodesk App Store at http://apps.exchange.autodesk.com/RVT/Detail/Index?id=appstore.exchange.autodesk.com%3amovetoanalytical%3aen

Here’s how it works

  1. Move the analytical model of a floor or beam away from the physical model with the Analytical Adjust command in the Revit UI
  2. Run the “Move to Analytical” API command
  3. Select the analytical model of a beam or floor that has been moved with the Analytical Adjust command
  4. The element will move into the position of its analytical model (note that for floors, this command will move the floor but will not change the shape of its sketch)

Keyboard Shortcut Tutor improved – new install available

I have made some improvements to the Keyboard Shortcut Tutor that you can download here:

The major change is that the reminder dialog is now shown after the command is complete instead of immediately after the ribbon button is pushed. This was needed to avoid a conflict with commands like Create Group and New Sheet that present a modal dialog box. For example, if you invoke the Wall tool from the ribbon, the reminder will now be shown after you finish creating walls.

Also fixed is the dialog background color is now always white but in the previous version appeared as black with certain Windows display settings. This made the black text in the dialog unreadable.

Q) When is 1 divided by 3 = 0?

A) When you are doing integer division in C#.

Dividing two integers always produces an integer. That is why 1/3 = 0.  You can either cast the integers into doubles (in the number2 example) or use doubles instead of integers (number3 example).

double number = 1 / 3;
double number2 = (double)1 / (double)3;
double number3 = 1.0 / 3.0;
TaskDialog.Show("Division","Your results are:\n" + number + "\n" + number2 + " \n" + number3);

divisionl

 


			

Download the Revit Keyboard Shortcut Tutor today!

Keyboard Shortcut Tutor

2012 Install  2013 Install Purchase License (only $4.99)
  • Become a Revit speed demon
  • Leave your co-workers in the dust
  • Increase your productivity

Boost Your BIM’s keyboard shortcut tutor gives you a friendly reminder in a small modeless dialog box when you use the mouse to click on a command that has a keyboard shortcut. A button in the dialog lists all shortcuts.

Free version provides reminders for shortcuts that contain the letter “W”. If you find it helpful and want reminders for all shortcuts, please purchase a license.

Finding Text Size as a Built-In Parameter

The TextNoteType class is where a property to find the size of a Text type would ideally be found. But it is not.

TextNoteType

However, all hope is not lost.

It is important to remember (and sometimes easy to forget), that there is also a huge set of parameters in the Revit API known as Built In Parameters. Many of these parameters work in the internal Revit code and not in the API, but many (such as TEXT_SIZE) are also perfectly usable in the API.

BuiltInParam

Usage:

TextNote textNote = doc.GetElement(uidoc.Selection.PickObject(ObjectType.Element).ElementId) as TextNote;
TextNoteType textNoteType = doc.GetElement(textNote.GetTypeId()) as TextNoteType;
Parameter textSizeParam = textNoteType.get_Parameter(BuiltInParameter.TEXT_SIZE);
TaskDialog.Show("Text Size", textSizeParam.AsDouble().ToString());

What views use which view templates? (2013 edition and better formatting)

View Templates got a big makeover in Revit 2013, so the previous post needs to be modified slightly to run in Revit 2013. I’ve also improved the format of the output so it looks like this:


---------------- Summary ---------------------------
Architectural Elevation: 4
Architectural Plan: 2
Architectural Reflected Ceiling Plan: 2
Site Plan: 1
Structural Framing Plan: 0
Structural Framing Elevation: 0
Architectural Section: 0
Site Section: 0
Structural Section: 0
Architectural Presentation 3D: 0
Architectural Presentation Elevation: 0
Export to Civil Engineering: 0

---------------- Details ---------------------------
'Architectural Elevation' is View Template for 4 views
Elevation East
Elevation North
Elevation West
Elevation South

'Architectural Plan' is View Template for 2 views
FloorPlan Level 1
FloorPlan Level 2

'Architectural Reflected Ceiling Plan' is View Template for 2 views
CeilingPlan Level 1
CeilingPlan Level 2

'Site Plan' is View Template for 1 views
FloorPlan Site

'Structural Framing Plan' is View Template for 0 views

'Structural Framing Elevation' is View Template for 0 views

'Architectural Section' is View Template for 0 views

'Site Section' is View Template for 0 views

'Structural Section' is View Template for 0 views

'Architectural Presentation 3D' is View Template for 0 views

'Architectural Presentation Elevation' is View Template for 0 views

'Export to Civil Engineering' is View Template for 0 views

The view parameter “Default View Template” has been renamed “View Template” and the API has a new property View.ViewTemplateId. 2013 also obsoleted Document.get_Element, replacing it with Document.GetElement.

public void TemplateUse()
{
    Document doc = this.ActiveUIDocument.Document;
    Dictionary<string, IList<string>> dict = new Dictionary<string, IList<string>>();
    foreach (View viewTemplate in (from v in new FilteredElementCollector(doc).OfClass(typeof(View)).Cast<View>() where v.IsTemplate select v))
    {
        IList<string> viewsUsed = new List<string>();
        foreach (View view in (from v in new FilteredElementCollector(doc).OfClass(typeof(View)).Cast<View>() where !(v.IsTemplate) select v))
        {
            ElementId id = view.ViewTemplateId;
            if (id != ElementId.InvalidElementId)
            {
                Element e = doc.GetElement(id);
                if (e.Name == viewTemplate.Name)
                    viewsUsed.Add(view.ViewType.ToString() + " " + view.Name);
            }
        }
        dict.Add(viewTemplate.Name, viewsUsed);
    }

    // sort the dictionary based on the number of views in each list
    var items = from pair in dict orderby pair.Value.Count descending select pair;

    string filename = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "ViewTemplateUsage.txt");

    using (StreamWriter sr = new StreamWriter(filename, false))
    {
        sr.WriteLine("---------------- Summary ---------------------------");

        foreach (KeyValuePair<string, IList<string>> pair in items)
        {
            sr.WriteLine(pair.Key + ": " + pair.Value.Count);
        }
        sr.WriteLine();

        sr.WriteLine("---------------- Details ---------------------------");
        foreach (KeyValuePair<string, IList<string>> pair in items)
        {
            sr.WriteLine("'" + pair.Key + "' is View Template for " + pair.Value.Count + " views");
            foreach (string name in pair.Value)
            {
                sr.WriteLine(name);
            }
            sr.WriteLine();
        }
    }
    Process.Start(filename);
}    

What views use which view templates? (2012 edition)

Steve wrote at Revit OpEd:

When I travel back and forth between Revit versions, say between 12 and 13, I find myself missing things. For example I wanted to see (in 2012) how many views were assigned to view templates and which ones were really being used. In 2013 we can add that parameter to a View List, 2012 not so much. In 2013 we can select a view template and see how many views are assigned to it, in 2012…you get the idea. I wish life and project conditions didn’t make it hard to “just upgrade”. Just do it, as soon as you can!

Sometimes when you can’t upgrade your RVT to a newer version of Revit, you can use the Revit API to accomplish something similar (or even better!) than what you would do in the newer release of Revit. Here is a Revit 2012 macro that outputs a text file listing all view templates with the count and names of the views that use it as the default view template:

'Architectural Elevation' is Default View Template for 4 views

Elevation East, Elevation North, Elevation West, Elevation South,

'Architectural Plan' is Default View Template for 2 views

FloorPlan Level 1, FloorPlan Level 2,

'Architectural Reflected Ceiling Plan' is Default View Template for 2 views

CeilingPlan Level 1, CeilingPlan Level 2,

'Site Plan' is Default View Template for 1 views

FloorPlan Site,

'Structural Framing Plan' is Default View Template for 0 views

'Structural Framing Elevation' is Default View Template for 0 views

'Architectural Section' is Default View Template for 0 views

'Site Section' is Default View Template for 0 views

'Structural Section' is Default View Template for 0 views

'Architectural Presentation 3D' is Default View Template for 0 views

'Architectural Presentation Elevation' is Default View Template for 0 views

'Export to Civil Engineering' is Default View Template for 0 views
public void TemplateUse()
{
    Document doc = this.ActiveUIDocument.Document;
    Dictionary<string, IList<string>> dict = new Dictionary<string, IList<string>>();
    foreach (View viewTemplate in (from v in new FilteredElementCollector(doc).OfClass(typeof(View)).Cast<View>() where v.IsTemplate select v))
    {
        IList<string> viewsUsed = new List<string>();
        foreach (View view in (from v in new FilteredElementCollector(doc).OfClass(typeof(View)).Cast<View>() where !(v.IsTemplate) select v))
        {
            Parameter p = view.get_Parameter("Default View Template");
            if (p != null)
            {
                ElementId id = p.AsElementId();
                if (id != ElementId.InvalidElementId)
                {
                    Element e = doc.get_Element(p.AsElementId());
                    if (e.Name == viewTemplate.Name)
                        viewsUsed.Add(view.ViewType.ToString() + " " + view.Name);
                }
            }
        }
        dict.Add(viewTemplate.Name, viewsUsed);
    }

    // sort the dictionary based on the number of views in each list
    var items = from pair in dict orderby pair.Value.Count descending select pair;

    string filename = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "ViewTemplateUsage.txt");

    using (StreamWriter sr = new StreamWriter(filename, false))
    {
        foreach (KeyValuePair<string, IList<string>> pair in items)
        {
            sr.WriteLine("'" + pair.Key + "' is Default View Template for " + pair.Value.Count + " views");
            string s = "";
            foreach (string name in pair.Value)
            {
                s += name + ", ";
            }
            sr.WriteLine(s);
            sr.WriteLine();
        }
    }
    Process.Start(filename);
}

Download links for the RevitAPI help files

After downloading these files, go to the File Properties dialog and click “Unblock” to allow them to display their contents.

Unblock

How to use Boost Your BIM source code to create working macros

A video showing the complete process of using use the code from these posts to create and compile a working macro.

https://boostyourbim.wordpress.com/2013/02/10/macro-to-quickly-fix-the-tofrom-room-parameter-for-doors/
https://boostyourbim.wordpress.com/2012/12/23/using-statements/

Set adaptive component parameters with placement point coordinates

A reader asked how to compute and schedule the placement point coordinates of adaptive component families. Here is a sample using the Parameter API and Dynamic Model Update to get and set those values.

private void Module_Startup(object sender, EventArgs e)
{
    AdaptivePointParamUpdater updater = new AdaptivePointParamUpdater(this.Application.ActiveAddInId);

    try
    {
    UpdaterRegistry.RegisterUpdater(updater);
    UpdaterRegistry.AddTrigger(updater.GetUpdaterId(), new ElementClassFilter(typeof(FamilyInstance)), Element.GetChangeTypeElementAddition());
    UpdaterRegistry.AddTrigger(updater.GetUpdaterId(), new ElementClassFilter(typeof(FamilyInstance)), Element.GetChangeTypeGeometry());
    }
    catch{}
}

public class AdaptivePointParamUpdater : IUpdater
{
    static AddInId m_appId;
    static UpdaterId m_updaterId;
    public AdaptivePointParamUpdater(AddInId id)
    {
        m_appId = id;
        m_updaterId = new UpdaterId(m_appId, new Guid("1BF1F6A2-4C06-42d4-97C1-D1B4EB593EFF"));
    }
    public void Execute(UpdaterData data)
    {
        Document doc = data.GetDocument();
        Autodesk.Revit.ApplicationServices.Application app = doc.Application;
        foreach (ElementId id in data.GetAddedElementIds())
        {
            adaptivePointParams(data.GetDocument(), id);
        }
        foreach (ElementId id in data.GetModifiedElementIds())
        {
            adaptivePointParams(data.GetDocument(), id);
        }
    }
    public string GetAdditionalInformation(){return "Data about adaptive parameters";}
    public ChangePriority GetChangePriority(){return ChangePriority.FloorsRoofsStructuralWalls;}
     public UpdaterId GetUpdaterId(){return m_updaterId;}
    public string GetUpdaterName(){return "AdaptivePoints";}

    private void adaptivePointParams(Document doc, ElementId id)
    {
        FamilyInstance fi = doc.GetElement(id) as FamilyInstance;
        if (fi != null && AdaptiveComponentInstanceUtils.IsAdaptiveComponentInstance(fi))
        {
            int ctr = 1;
            foreach (ElementId elementId in AdaptiveComponentInstanceUtils.GetInstancePlacementPointElementRefIds(fi))
            {
                ReferencePoint rp = doc.GetElement(elementId) as ReferencePoint;
                XYZ position = rp.Position;
                if (ctr == 1)
                {
                    fi.get_Parameter("point1x").Set(Math.Round(position.X,3));
                    fi.get_Parameter("point1y").Set(Math.Round(position.Y,3));
                    fi.get_Parameter("point1z").Set(Math.Round(position.Z,3));
                }
                else if (ctr == 2)
                {
                    fi.get_Parameter("point2x").Set(Math.Round(position.X,3));
                    fi.get_Parameter("point2y").Set(Math.Round(position.Y,3));
                    fi.get_Parameter("point2z").Set(Math.Round(position.Z,3));
                }                    
                ctr++;
            }
        }
    }        
}

Macro to quickly fix the To/From Room parameter for doors

Steve, the wizard of revitoped.blogspot.com, suggested:

It would be cool to use the API to allow a user to pick a door and room to resolve the to/from settings. A user was lamenting the labor hassle of fixing to/from settings because people are mirroring and copying doors which doesn’t necessarily inherit the correct room ownership.

This macro works as follows

  • Select a door or door tag
  • Select the To Room (either the Room or the Room Tag)
  • Repeat as desired, press the ESC key when done
public void FlipRoom()
{
    UIDocument uidoc = this.ActiveUIDocument;
    Document doc = uidoc.Document;
    FamilyInstance door = null;
    string doorMark = "";
    while (true) // create an infinite loop that will be ended by the "return" statement in the catch block
    {
        try
        {
            Element element = doc.GetElement(uidoc.Selection.PickObject(ObjectType.Element, "Select a door or door tag"));

            if (element is FamilyInstance) // if door is selected
                door = element as FamilyInstance;
            else if (element is IndependentTag) // if door tag is selected
            {
                IndependentTag tag = element as IndependentTag;
                door = doc.GetElement(tag.TaggedLocalElementId) as FamilyInstance;
            }
            doorMark = door.get_Parameter("Mark").AsString();
        }
        catch
        {
            return; // end the command when the user presses ESC when prompted for a door
        }

        // after the user has selected a door, prompt for selection of a room
        Element e = doc.GetElement(uidoc.Selection.PickObject(ObjectType.Element, "Select To Room for door " + doorMark));

        // Get the room element from the selected object
        Room room = null;
        if (e is RoomTag)
        {
            RoomTag rt = e as RoomTag;
            room = rt.Room;
        }
        else if (e is Room)
        {
            room = e as Room;
        }

        if (room != null && door.ToRoom.Id.IntegerValue != room.Id.IntegerValue) // if the selected room is not already the To Room
        {
            using (Transaction t = new Transaction(doc,"Door " + doorMark + " to room = " + room.Number))
            {
                t.Start();
                door.FlipFromToRoom(); // Flip the settings of "From Room" and "To Room" for the door 
                t.Commit();
            }
        }
    }
}

Setting door position relative to nearby walls

A reader sent the image on the right and asked: “can we make door with specific distance to face of waDoorPositionll like 20 cm without every time need to adjust distance in temporary dimension ?”

This seemed like a good excuse to stop writing code dealing with Family Parameters (I was getting tired of writing it, were you getting tired of reading about it?).

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

    // establish an offset of 20cm that will be applied to the door and wall
    // Revit's internal units for distance is feet
    double doorToWallDistance = 20 / (12 * 2.54); // convert 20 cm to 1 ft

    try // try/catch block with PickObject is used to give the user a way to get out of the infinite loop of while (true)
        // PickObject throws an exception when user aborts from selection
    {
        while (true)
        {
            FamilyInstance door = doc.GetElement(uidoc.Selection.PickObject(ObjectType.Element, "Select a door. ESC when finished.").ElementId) as FamilyInstance;
            double doorWidth = door.Symbol.get_Parameter(BuiltInParameter.DOOR_WIDTH).AsDouble();

            Wall sideWall = doc.GetElement(uidoc.Selection.PickObject(ObjectType.Element, "Select a wall. ESC when finished.").ElementId) as Wall;
            double sideWallWidth = sideWall.Width;

            // get the curve that defines the centerline of the side wall
            LocationCurve sideWallLocationCurve = sideWall.Location as LocationCurve;
            Curve sideWallCurve = sideWallLocationCurve.Curve;

            // get the curve that defines the centerline of the wall that hosts the door
            Wall hostWall = door.Host as Wall;
            LocationCurve hostWallLocationCurve = hostWall.Location as LocationCurve;
            Curve hostWallCurve = hostWallLocationCurve.Curve;

            // find the point of intersection of these two wall curves (intersectionXYZ)
            // and the position of this point on the wall that hosts the door (intersectionParam)
            IntersectionResultArray ira = new IntersectionResultArray();
            SetComparisonResult scr = sideWallCurve.Intersect(hostWallCurve, out ira);
            var iter = ira.GetEnumerator();
            iter.MoveNext();
            IntersectionResult ir = iter.Current as IntersectionResult;
            XYZ intersectionXYZ = ir.XYZPoint;
            double intersectionParam = hostWallCurve.Project(intersectionXYZ).Parameter;

            // find the position of the door in its host wall
            LocationPoint doorPoint = door.Location as LocationPoint;
            XYZ doorXYZ = doorPoint.Point;
            double doorParam = hostWallCurve.Project(doorXYZ).Parameter;

            // compute the translation vector between the edge of the door closest to the wall and the side face of the wall
            XYZ translation = null;
            XYZ doorEdgeXYZ = null;
            XYZ intersectionOffsetXYZ = null;
            if (intersectionParam > doorParam)
            {
                intersectionOffsetXYZ = hostWallCurve.Evaluate(intersectionParam - doorToWallDistance - sideWallWidth/2, false);
                doorEdgeXYZ = hostWallCurve.Evaluate(doorParam + doorWidth/2, false);
                translation = intersectionOffsetXYZ.Subtract(doorEdgeXYZ);
            }
            else
            {
                intersectionOffsetXYZ = hostWallCurve.Evaluate(intersectionParam + doorToWallDistance + sideWallWidth/2, false);
                doorEdgeXYZ = hostWallCurve.Evaluate(doorParam - doorWidth/2, false);
                translation = doorEdgeXYZ.Subtract(intersectionOffsetXYZ).Negate();
            }

            // Move the door
            using (Transaction t = new Transaction(doc,"move door"))
            {
                t.Start();
                ElementTransformUtils.MoveElement(doc,door.Id,translation);
                t.Commit();
            }
        }
    }
    catch{}
}

Bulk Family Parameter Editing Improvements

Thanks to everyone for their enthusiasm and feedback on my recent posts about exporting family parameters to Excel and modifying the parameter data.

I’ve added the Shared Parameter GUIDs, the ability to modify parameters stored as text, integer, and double values, and UI for specifying folders and files. Are there other changes that would be valuable to make before I publish the tool?

API code for all languages (when possible) with TaskDialog Ids and WriteJournalComment

Arnost makes a good comment below reminding us to think about how Revit and our API applications will work with non-English versions of Revit.

Please remember that the text will not always be in English! It comes from resources and will be properly localized in foreign versions of Revit. Using the string locally is all right, but it is better to rely on Dialog Id, which should also be available (although not always is) in the event argument.

He was writing in response to the code I posted:

t.Message == "The floor/roof overlaps the highlighted wall(s). Would you like to join geometry and cut the overlapping volume out of the wall(s)?"

It would be better to avoid including the English text in the API logic, but sometimes we have no choice. Here are 5 task dialogs – 2 have a DialogId and for 3 that property is empty. And when there is no DialogId the only option is to base the comparison on the text string of the message.

‘C 02-Feb-2013 14:16:39.716; 1:< TaskDialogShowingEventArgs,The floor/roof overlaps the highlighted wall(s). Would you like to join geometry and cut the overlapping volume out of the wall(s)?,,

‘C 02-Feb-2013 14:16:21.362;   1:< TaskDialogShowingEventArgs,Would you like to attach the highlighted walls to the roof?,,

‘C 02-Feb-2013 14:15:41.234; 1:< TaskDialogShowingEventArgs,Would you like to rename corresponding views?,,

‘C 02-Feb-2013 14:21:03.890; 2:< TaskDialogShowingEventArgs,Do you want to save changes to uni2.rvt?,TaskDialog_Save_File,

‘C 02-Feb-2013 14:22:10.362; 1:< TaskDialogShowingEventArgs,You are trying to load the family Table-Dining Round w Chairs, which already exists in this project. What do you want to do?,TaskDialog_Family_Already_Exists,

Here’s the macro code to write the TaskDialog message text and id to the journal file.

private void Module_Startup(object sender, EventArgs e)
{
    UIApplication uiapp = new UIApplication(this.Application);
    uiapp.DialogBoxShowing += new EventHandler<DialogBoxShowingEventArgs>(taskDialogInfo);
}

private void taskDialogInfo(object o, DialogBoxShowingEventArgs e)
{
    TaskDialogShowingEventArgs t = e as TaskDialogShowingEventArgs;
    if (t != null)
        this.Application.WriteJournalComment("TaskDialogShowingEventArgs," + t.Message + "," + t.DialogId + ",",true);
}

In most cases it can be more convenient to show the data (t.Message and t.DialogId) in a TaskDialog, but you can’t show a TaskDialog during the DialogBoxShowing event when Revit is trying to show its own dialog box.

Using “Step Into” to look at the values in Sharp Develop usually works, but you can’t step into a function that is triggered when an event occurs.

So WriteJournalComment is a great solution in this case.

How to Automatically Dismiss a Revit dialog

For my friend who asked:

Is it possible to disable the pop-up, when you edit a floor: -Would you like walls that go up to his floor’s level to attach to its bottom?- I never want to do this, it’s annoying

Here is how to automatically dismiss that or any other Message Box or Task Dialog

private void Module_Startup(object sender, EventArgs e)
{
    UIApplication uiapp = new UIApplication(this.Application);
    // Subscribe to the DialogBoxShowing event to be notified when Revit is about to show a dialog box or a message box. 
    uiapp.DialogBoxShowing += new EventHandler<DialogBoxShowingEventArgs>(dismissFloorQuestion);
}

private void dismissFloorQuestion(object o, DialogBoxShowingEventArgs e)
{
    // DialogBoxShowingEventArgs has two subclasses - TaskDialogShowingEventArgs & MessageBoxShowingEventArgs
    // In this case we are interested in this event if it is TaskDialog being shown. 
    TaskDialogShowingEventArgs t = e as TaskDialogShowingEventArgs;
    if (t != null && t.Message == "The floor/roof overlaps the highlighted wall(s). Would you like to join geometry and cut the overlapping volume out of the wall(s)?")
    {
        // Call OverrideResult to cause the dialog to be dismissed with the specified return value
        // (int) is used to convert the enum TaskDialogResult.No to its integer value which is the data type required by OverrideResult
        e.OverrideResult((int)TaskDialogResult.No);
    }
}