Call class from windows form

Call class from windows form

Anonymous
Not applicable
3,471 Views
10 Replies
Message 1 of 11

Call class from windows form

Anonymous
Not applicable

Hello,

 

I creating an application for revit addin in which when we click on addin it open the windows form .

 

Form contain combobox and button, if we select an item from combobox the clicked button it run the class which we have call on that click button.

 

Addin Ribbon code:-

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Autodesk.Revit.UI;
using System.Reflection;

namespace FormDemo
{
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
public class Class1 : IExternalApplication
{
public Result OnShutdown(UIControlledApplication application)
{
return Result.Succeeded;
}

public Result OnStartup(UIControlledApplication application)
{
RibbonPanel ribbonPanel = application.CreateRibbonPanel("Form");
string thisAssemblyPath = Assembly.GetExecutingAssembly().Location;
//string assembly = @"D:\Software\FormDemo\FormDemo\bin\Debug\FormDemo.dll";

PushButtonData bOne = new PushButtonData("ButtonNameA", "FormDemo1",
thisAssemblyPath, "FormDemo.Class2");

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

return Result.Succeeded;
}
}
}

 

 

 

Class2 Code:-

 

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.ApplicationServices;

namespace FormDemo
{
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
class Class2 : IExternalCommand
{
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{

Form1 fm = new Form1();
fm.Show();

return Result.Succeeded;
}
}
}

 

 

 

Form code:-

 

using System;
using Autodesk.Revit.UI;

using Autodesk.Revit.DB;

 

namespace FormDemo
{

[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]

 

public partial class Form1 : System.Windows.Forms.Form
{
ExternalCommandData commandData;

// ElementSet elements;
// string message=null;
public Form1()
{
InitializeComponent();
}

 

public void Form1_Load(object sender, EventArgs e)
{
comboBox1.Items.Add("Wall And Column");

}

public void button1_Click(object sender, EventArgs e)
{

if (comboBox1.SelectedItem == "Wall And Column")
{
try
{
//In this block ,How I call WCjoin class and it execute the code of that class
}
catch(Exception g)
{
TaskDialog.Show("revit", "error is occured"+g);
}

TaskDialog.Show("revit", "Joined Wall And Column");
}

}

 }

}

 

 

 

WCjoin class Code:-

 

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

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

namespace FormDemo
{
[Transaction(TransactionMode.Manual)]
class WCjoin
{

public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{

UIApplication uiApp = commandData.Application;
UIDocument uidoc = uiApp.ActiveUIDocument;
Document doc = uidoc.Document;

//-----------get walls on the active view-----------

FilteredElementCollector collWalls = new FilteredElementCollector(doc, doc.ActiveView.Id);
collWalls.OfClass(typeof(Wall));

foreach (Wall w in collWalls)
{

FilteredElementCollector collColumnsOnThisWall = new FilteredElementCollector(doc, doc.ActiveView.Id);

collColumnsOnThisWall.OfClass(typeof(FamilyInstance));
collColumnsOnThisWall.OfCategory(BuiltInCategory.OST_StructuralColumns);

foreach (FamilyInstance column in collColumnsOnThisWall)
{
using (Transaction t = new Transaction(doc, "Join All Walls/Column"))
{
t.Start();
JoinGeometryUtils.JoinGeometry(doc, w, column);
t.Commit();
}


}

}
TaskDialog.Show("revit", "in class");
return Result.Succeeded;
}


}

}

 

//If i write the code in the form.cs class in try block like this

 

try
{
WCjoin wcj = new WCjoin();
wcj.Execute(commandData, ref message1, elements);
}

 

//it give me error..I attach image which show error.

 

 

 

I had added some screen shot..plz tell me what i should do!

 

0 Likes
Accepted solutions (1)
3,472 Views
10 Replies
Replies (10)
Message 2 of 11

Moustafa_K
Collaborator
Collaborator
Accepted solution

it will not work because you did not pass the variable commandData and  message and element to the form you instantiated... at this line

 

Form1 fm = new Form1();

you need to pass the ExternalCommandData which the only variable you need to do excute WCjoin

 

 

 

read this modified code to help you resolve this 

 

 

Class2 Code:-

 

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.ApplicationServices;

namespace FormDemo
{
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
class Class2 : IExternalCommand
{
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{

Form1 fm = new Form1(commandData);
fm.Show();

return Result.Succeeded;
}
}
}

 

 

 

Form code:-

 

using System;
using Autodesk.Revit.UI;

using Autodesk.Revit.DB;

 

namespace FormDemo
{

[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]

 

public partial class Form1 : System.Windows.Forms.Form
{
ExternalCommandData commandData;

// ElementSet elements;
// string message=null;
public Form1(ExternalCommandData commandDatax)
{
InitializeComponent();
commandData = commandDatax;
}

 

public void Form1_Load(object sender, EventArgs e)
{
comboBox1.Items.Add("Wall And Column");

}

public void button1_Click(object sender, EventArgs e)
{

if (comboBox1.SelectedItem == "Wall And Column")
{
try
{
//In this block ,How I call WCjoin class and it execute the code of that class

WCjoin wcj = new WCjoin();
wcj.Execute(commandData, ref message1, elements);
wcj.Execute(commandData);

}
catch(Exception g)
{
TaskDialog.Show("revit", "error is occured"+g);
}

TaskDialog.Show("revit", "Joined Wall And Column");
}

}

 }

}

 

 

 

WCjoin class Code:-

 

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

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

namespace FormDemo
{
[Transaction(TransactionMode.Manual)]
class WCjoin
{

public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
public Result Execute(ExternalCommandData commandData)
{

UIApplication uiApp = commandData.Application;
UIDocument uidoc = uiApp.ActiveUIDocument;
Document doc = uidoc.Document;

//-----------get walls on the active view-----------

FilteredElementCollector collWalls = new FilteredElementCollector(doc, doc.ActiveView.Id);
collWalls.OfClass(typeof(Wall));

foreach (Wall w in collWalls)
{

FilteredElementCollector collColumnsOnThisWall = new FilteredElementCollector(doc, doc.ActiveView.Id);

collColumnsOnThisWall.OfClass(typeof(FamilyInstance));
collColumnsOnThisWall.OfCategory(BuiltInCategory.OST_StructuralColumns);

foreach (FamilyInstance column in collColumnsOnThisWall)
{
using (Transaction t = new Transaction(doc, "Join All Walls/Column"))
{
t.Start();
JoinGeometryUtils.JoinGeometry(doc, w, column);
t.Commit();
}


}

}
TaskDialog.Show("revit", "in class");
return Result.Succeeded;
}


}

}

 

 

Hint!... try to simplify your code as much as possible.

 

Let us know if this did work

 

 *** Update 1

you also need to use 

fm.ShowDialog ();

and not 

fm.Show ();

 

otherwise you need to use Idlying event handler.

 

and do not forget to close your form after finishing

 

public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{

Form1 fm = new Form1(commandData);
fm.Show();
fm.ShowDialog();

fm.Close(); return Result.Succeeded; }

 

Moustafa Khalil
Cropped-Sharp-Bim-500x125-Autodesk-1
Message 3 of 11

Anonymous
Not applicable

Thank you for reply.Its working.

 

0 Likes
Message 4 of 11

Anonymous
Not applicable

One more thing I want to ask that after addin is clicked the form is display but if we want to access revit it not allow to use it. After cancel the form we can access it.If we want to access both form and revit how we can achieve. What I should do to work parallel with both. 

0 Likes
Message 5 of 11

Moustafa_K
Collaborator
Collaborator
you need to use Idling even handler

check this website
http://thebuildingcoder.typepad.com/blog/2011/09/modeless-forms-in-revit.html


--
--
Best Regards,

--------------------------------------------------
Mostafa Khalil
Moustafa Khalil
Cropped-Sharp-Bim-500x125-Autodesk-1
0 Likes
Message 6 of 11

Anonymous
Not applicable

I am not getting it. can you explain me?

 

0 Likes
Message 7 of 11

Anonymous
Not applicable

One more changes I want to do in this project that if i write a code in WCjoin class for joining wall and column.

 

If I take one more drop down list in the form that drop down list contain levels of the project means ground level,first floor level like that which we currenty working on the revit project in a active view. How I get that level in the drop down list?

 

And one more thing after selecting item from first drop down list (first drop down contain the item for join wall and column) and we select second drop down for selecting the levels for joining wall and column. How I achieve this also?

 

 

Example:-

 

1st drop down has a string 

2nd drop down conatins levels(if I select 1st floor level)

 

If I select both item from drop down list then click on join button the it join only first floor elements(wall and column) .It could not join other levels element(wall and column).

 

 

What changes should I do for achieve my requirement?

 

I using the code which I previously posted.

 

Plz tell me solution.

0 Likes
Message 8 of 11

Anonymous
Not applicable

I want to add progress bar in this project for processing when class is executing..I want to do like progress bar also updating and class also executing that means both runs parallely. How can I achieve this target?

 

I use same project in this post.

 

Plz tell me solution

0 Likes
Message 9 of 11

Anonymous
Not applicable

I tried some some for this

 

 

private void button1_Click(object sender, EventArgs e)//Join button clicked
{
timer1.Stop();
progressBar1.Value = 0;
timer1.Start();
t.Start();

 

public void button1_Click(object sender, EventArgs e)
{

if (comboBox1.SelectedItem == "Wall And Column")
{
try
{
//In this block ,How I call WCjoin class and it execute the code of that class

WCjoin wcj = new WCjoin();

wcj.Execute(commandData);

}
catch(Exception g)
{
TaskDialog.Show("revit", "error is occured"+g);
}

TaskDialog.Show("revit", "Joined Wall And Column");
}

}



private void timer1_Tick(object sender, EventArgs e)
{
progressBar1.Increment(5);

}





I use this code but progress bar is update after class WCjoin is executed.
It not running parallely.
Plz tell me what update should I do in this code?

 

0 Likes
Message 10 of 11

Anonymous
Not applicable

One more changes I want to do in this project that if i write a code in WCjoin class for joining wall and column.

 

If I take one more drop down list in the form that drop down list contain levels of the project means ground level,first floor level like that which we currenty working on the revit project in a active view. How I get that level in the drop down list?

 

And one more thing after selecting item from first drop down list (first drop down contain the item for join wall and column) and we select second drop down for selecting the levels for joining wall and column. How I achieve this also?

 

 

Example:-

 

1st drop down has a string 

2nd drop down conatins levels(if I select 1st floor level)

 

If I select both item from drop down list then click on join button the it join only first floor elements(wall and column) .It could not join other levels element(wall and column).

 

 

What changes should I do for achieve my requirement?

 

I using the code which I previously posted.

 

Plz tell me solution.

0 Likes
Message 11 of 11

Anonymous
Not applicable

I want to add progress bar in this project for processing when class is executing..I want to do like progress bar also updating and class also executing that means both runs parallely. How can I achieve this target?

 

I use same project in this post.

 

Plz tell me solution

 

 

I tried some some for this

 

 

private void button1_Click(object sender, EventArgs e)//Join button clicked
{
timer1.Stop();
progressBar1.Value = 0;
timer1.Start();
t.Start();

 

public void button1_Click(object sender, EventArgs e)
{

if (comboBox1.SelectedItem == "Wall And Column")
{
try
{
//In this block ,How I call WCjoin class and it execute the code of that class

WCjoin wcj = new WCjoin();

wcj.Execute(commandData);

}
catch(Exception g)
{
TaskDialog.Show("revit", "error is occured"+g);
}

TaskDialog.Show("revit", "Joined Wall And Column");
}

}



private void timer1_Tick(object sender, EventArgs e)
{
progressBar1.Increment(5);

}





I use this code but progress bar is update after class WCjoin is executed.
It not running parallely.
Plz tell me what update should I do in this code?
0 Likes