Good morning.
I am trying and trying to understand a little about “Forms”.
I have developed the following code in dynamo “PYHTON SCRIPT” of revit 2020 that handles IRON PYTHON 2.7 and so far everything was going well until I am trying to implement in the code the “BOMCOLIST” in each of the cells of the “Covering” column where I can show the default value of the “covering other faces” and when clicking on said cell it shows me the other covering configurations that exist in the document, in this way I can select and change the type of covering through my DATA GRID VIEW.
I share the code that is in dynamo.
Thank you very much for your time.
WindowsForm.dyn (9.9 KB)
Hi,
you need to implement an DataGridViewComboBoxColumn
, I recently shared an example of this here
1 Like
I have the following problem:
What happens is that the Data Grid View only shows me 26 elements when I have 400 elements in IN[0]. What is the reason for this?
import clr
import sys
import System
from System.Collections.Generic import List
# Importar Revit API
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
import Autodesk.Revit.DB as DB
clr.AddReference('System.Drawing')
clr.AddReference('System.Windows.Forms')
import System.Drawing
import System.Windows.Forms
from System.Drawing import *
from System.Windows.Forms import *
clr.AddReference('System.Data')
from System.Data import *
# Importar transactionManager y DocumentManager (RevitServices es específico de Dynamo)
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
# Obtener el documento actual de Revit
doc = DocumentManager.Instance.CurrentDBDocument
uidoc = DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application
sdkNumber = int(app.VersionNumber)
class FormSetWkset2(Form):
def __init__(self, lst_elems, lst_wkset, recubrimientos, recubrimiento_valores):
self._lst_wkset = lst_wkset
self._lst_elems = lst_elems
self._recubrimientos = recubrimientos
self._recubrimiento_valores = recubrimiento_valores
self._set_elemTypeId = set(x.GetTypeId() for x in lst_elems)
self._lst_elemType = [doc.GetElement(xId) for xId in self._set_elemTypeId if xId != ElementId.InvalidElementId]
self._wksetTable = doc.GetWorksetTable()
self._lst_elemType = sorted(self._lst_elemType, key=lambda x: x.FamilyName)
self._tableDataType = DataTable("ElementType")
self._tableDataType.Columns.Add("Element", DB.Element)
self._tableDataType.Columns.Add("FamilyName", System.String)
self._tableDataType.Columns.Add("Name", System.String)
self._tableDataType.Columns.Add("Categorie", System.String)
for x in self._lst_elemType:
self._tableDataType.Rows.Add(x, x.FamilyName, Element.Name.GetValue(x), x.Category.Name)
self._tableDataWkset = DataTable("Wkset")
self._tableDataWkset.Columns.Add("Workset", DB.Workset)
self._tableDataWkset.Columns.Add("Name", System.String)
for x in self._lst_wkset:
self._tableDataWkset.Rows.Add(x, x.Name)
self.pairLst = []
self.InitializeComponent()
def InitializeComponent(self):
dataGridViewCellStyle11 = System.Windows.Forms.DataGridViewCellStyle()
self._buttonOK = System.Windows.Forms.Button()
self._dataGridView1 = System.Windows.Forms.DataGridView()
self._groupBox1 = System.Windows.Forms.GroupBox()
self._ComboBoxValue = System.Windows.Forms.DataGridViewComboBoxColumn()
self._dataGridView1.BeginInit()
self._groupBox1.SuspendLayout()
self.SuspendLayout()
self.Shown += self.Form1_Shown
self._buttonOK.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right
self._buttonOK.Location = System.Drawing.Point(1090, 480)
self._buttonOK.Name = "buttonOK"
self._buttonOK.Size = System.Drawing.Size(95, 35)
self._buttonOK.TabIndex = 2
self._buttonOK.Text = "OK"
self._buttonOK.UseVisualStyleBackColor = True
self._buttonOK.Click += self.ButtonOKClick
dataGridViewCellStyle11.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft
dataGridViewCellStyle11.BackColor = System.Drawing.SystemColors.Control
dataGridViewCellStyle11.Font = System.Drawing.Font("Microsoft Sans Serif", 8.25, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, 0)
dataGridViewCellStyle11.ForeColor = System.Drawing.SystemColors.WindowText
dataGridViewCellStyle11.SelectionBackColor = System.Drawing.SystemColors.Highlight
dataGridViewCellStyle11.SelectionForeColor = System.Drawing.SystemColors.HighlightText
dataGridViewCellStyle11.WrapMode = getattr(System.Windows.Forms.DataGridViewTriState, "True")
self._dataGridView1.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle11
self._dataGridView1.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right
self._dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize
self._dataGridView1.EditMode = DataGridViewEditMode.EditOnEnter
self._dataGridView1.AllowUserToAddRows = False
self._dataGridView1.Location = System.Drawing.Point(6, 28)
self._dataGridView1.Name = "dataGridView1"
self._dataGridView1.Size = System.Drawing.Size(1160, 420)
self._dataGridView1.TabIndex = 3
self._dataGridView1.DataSource = self._tableDataType
self._dataGridView1.DataError += self.DataGridViewError
self._ComboBoxValue.HeaderText = "Recubrimiento"
self._ComboBoxValue.Name = "Recubrimiento"
self._ComboBoxValue.Width = 200
self._groupBox1.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right
self._groupBox1.Controls.Add(self._dataGridView1)
self._groupBox1.Location = System.Drawing.Point(12, 12)
self._groupBox1.Name = "groupBox1"
self._groupBox1.Size = System.Drawing.Size(1180, 460)
self._groupBox1.TabIndex = 4
self._groupBox1.TabStop = False
self._groupBox1.Text = "Detalles de Elementos"
self.ClientSize = System.Drawing.Size(1200, 530)
self.MinimumSize = self.ClientSize + System.Drawing.Size(20, 20)
self.Controls.Add(self._groupBox1)
self.Controls.Add(self._buttonOK)
self.Name = "Form27"
self.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Show
self.Text = "Asignar Recubrimiento"
self._dataGridView1.EndInit()
self._groupBox1.ResumeLayout(False)
self.ResumeLayout(False)
def Form1_Shown(self, sender, e):
self.SetCellComboBoxItems()
def SetCellComboBoxItems(self):
self._dataGridView1.Columns.Add(self._ComboBoxValue)
for i in range(self._dataGridView1.Rows.Count):
dgvcbc = self._dataGridView1.Rows[i].Cells[4]
dgvcbc.DataSource = self._recubrimiento_valores
# Establecer el valor predeterminado de la celda
dgvcbc.Value = self._recubrimientos[i]
self._dataGridView1.Columns["Element"].Visible = False
for idx, col in enumerate(self._dataGridView1.Columns):
if idx >= 3:
col.Width = 200
else:
col.Width = 250
def DataGridViewError(self, sender, e):
print(e.Exception)
def ButtonOKClick(self, sender, e):
self.pairLst = []
for i in range(self._dataGridView1.Rows.Count):
elem_symbol = self._dataGridView1.Rows[i].Cells[0].Value
wkset_name = self._dataGridView1.Rows[i].Cells[4].Value
if elem_symbol is not None and wkset_name is not None:
strDataExpression = "[Name] = '" + wkset_name + "'"
filterP = System.Predicate[DataRow](lambda x: x is not None)
dtRowA = System.Array.Find[DataRow](self._tableDataWkset.Select(strDataExpression), filterP)
wkset = dtRowA["Workset"]
if elem_symbol is not None:
self.pairLst.append([elem_symbol, wkset])
self.Close()
lst_Elements = UnwrapElement(IN[0])
lst_Wkset = FilteredWorksetCollector(doc).OfKind(WorksetKind.UserWorkset).ToWorksets()
# Obtener valores de recubrimiento actuales para cada elemento
recubrimientos = []
for e in lst_Elements:
para = e.get_Parameter(BuiltInParameter.CLEAR_COVER_OTHER)
recubrimiento = None
if para is None:
recubrimiento = "Error"
else:
idd = para.AsElementId()
if idd.IntegerValue == -1:
recubrimiento = "Sin asignar"
else:
rec = doc.GetElement(idd).CoverDistance * 0.3048
recubrimiento = rec
recubrimientos.append(recubrimiento)
# Obtener todos los valores posibles de recubrimiento para la lista desplegable
Recubrimientos = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_CoverType)
rec_nombre = []
for i in Recubrimientos:
nom = i.get_Parameter(BuiltInParameter.COVER_TYPE_NAME).AsString()
rec_nombre.append(nom)
form = FormSetWkset2(lst_Elements, lst_Wkset, recubrimientos, rec_nombre)
form.ShowDialog()
OUT = form.pairLst
because in this example, I use Elements Type instead of instances
see this lines
Thanks for pointing out the problem, thank you,
Now it happens that I have my form as I wish and the ONLY thing I WANT is to be able to move the Overlay column after Category and when I try to do so it closes or an index error appears… could you please help me with being able to move my column to the position I want? I wish
import clr
import sys
import System
from System.Collections.Generic import List
# Importar Revit API
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
import Autodesk.Revit.DB as DB
clr.AddReference('System.Drawing')
clr.AddReference('System.Windows.Forms')
import System.Drawing
import System.Windows.Forms
from System.Drawing import *
from System.Windows.Forms import *
clr.AddReference('System.Data')
from System.Data import *
# Importar transactionManager y DocumentManager (RevitServices es específico de Dynamo)
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
# Obtener el documento actual de Revit
doc = DocumentManager.Instance.CurrentDBDocument
uidoc = DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application
sdkNumber = int(app.VersionNumber)
class FormSetCover(Form):
def __init__(self, lst_elems, recubrimientos, recubrimiento_valores):
self._lst_elems = lst_elems # Lista de elementos de Revit
self._recubrimientos = recubrimientos
self._recubrimiento_valores = recubrimiento_valores
# Crear la tabla con las instancias individuales
self._tableDataType = DataTable("ElementType")
self._tableDataType.Columns.Add("Element", DB.Element)
self._tableDataType.Columns.Add("FamilyName", System.String)
self._tableDataType.Columns.Add("Name", System.String)
self._tableDataType.Columns.Add("Categorie", System.String)
# Añadir cada instancia a la tabla
for elem, rec in zip(self._lst_elems, self._recubrimientos):
self._tableDataType.Rows.Add(
elem,
elem.Symbol.FamilyName if hasattr(elem, "Symbol") else "N/A",
Element.Name.GetValue(elem),
elem.Category.Name if elem.Category else "N/A"
)
self.pairLst = [] # Para almacenar resultados
self.InitializeComponent()
def InitializeComponent(self):
dataGridViewCellStyle11 = System.Windows.Forms.DataGridViewCellStyle()
self._buttonOK = System.Windows.Forms.Button()
self._dataGridView1 = System.Windows.Forms.DataGridView()
self._groupBox1 = System.Windows.Forms.GroupBox()
self._ComboBoxValue = System.Windows.Forms.DataGridViewComboBoxColumn()
self._dataGridView1.BeginInit()
self._groupBox1.SuspendLayout()
self.SuspendLayout()
self.Shown += self.Form1_Shown
# Botón OK
self._buttonOK.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right
self._buttonOK.Location = System.Drawing.Point(1090, 480)
self._buttonOK.Name = "buttonOK"
self._buttonOK.Size = System.Drawing.Size(95, 35)
self._buttonOK.TabIndex = 2
self._buttonOK.Text = "OK"
self._buttonOK.UseVisualStyleBackColor = True
self._buttonOK.Click += self.ButtonOKClick
# Configuración de DataGridView
dataGridViewCellStyle11.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft
dataGridViewCellStyle11.BackColor = System.Drawing.SystemColors.Control
dataGridViewCellStyle11.Font = System.Drawing.Font("Microsoft Sans Serif", 8.25, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, 0)
dataGridViewCellStyle11.ForeColor = System.Drawing.SystemColors.WindowText
dataGridViewCellStyle11.SelectionBackColor = System.Drawing.SystemColors.Highlight
dataGridViewCellStyle11.SelectionForeColor = System.Drawing.SystemColors.HighlightText
dataGridViewCellStyle11.WrapMode = getattr(System.Windows.Forms.DataGridViewTriState, "True")
self._dataGridView1.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle11
self._dataGridView1.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right
self._dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize
self._dataGridView1.EditMode = DataGridViewEditMode.EditOnEnter
self._dataGridView1.AllowUserToAddRows = False
self._dataGridView1.Location = System.Drawing.Point(6, 28)
self._dataGridView1.Name = "dataGridView1"
self._dataGridView1.Size = System.Drawing.Size(1160, 420)
self._dataGridView1.TabIndex = 3
self._dataGridView1.DataSource = self._tableDataType
self._dataGridView1.DataError += self.DataGridViewError
# Añadir la columna ComboBox
self._ComboBoxValue.HeaderText = "Recubrimiento"
self._ComboBoxValue.Name = "Recubrimiento"
self._ComboBoxValue.Width = 200
self._ComboBoxValue.DataSource = self._recubrimiento_valores
self._dataGridView1.Columns.Add(self._ComboBoxValue)
# Grupo para DataGridView
self._groupBox1.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right
self._groupBox1.Controls.Add(self._dataGridView1)
self._groupBox1.Location = System.Drawing.Point(12, 12)
self._groupBox1.Name = "groupBox1"
self._groupBox1.Size = System.Drawing.Size(1180, 460)
self._groupBox1.TabIndex = 4
self._groupBox1.TabStop = False
self._groupBox1.Text = "Detalles de Elementos"
# Configuración de la ventana principal
self.ClientSize = System.Drawing.Size(1200, 530)
self.MinimumSize = self.ClientSize + System.Drawing.Size(20, 20)
self.Controls.Add(self._groupBox1)
self.Controls.Add(self._buttonOK)
self.Name = "Form27"
self.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Show
self.Text = "Asignar Recubrimiento"
self._dataGridView1.EndInit()
self._groupBox1.ResumeLayout(False)
self.ResumeLayout(False)
def Form1_Shown(self, sender, e):
self.SetCellComboBoxItems()
def SetCellComboBoxItems(self):
for i in range(self._dataGridView1.Rows.Count):
dgvcbc = self._dataGridView1.Rows[i].Cells["Recubrimiento"]
dgvcbc.Value = self._recubrimientos[i]
self._dataGridView1.Columns["Element"].Visible = False
def DataGridViewError(self, sender, e):
print(e.Exception)
def ButtonOKClick(self, sender, e):
self.pairLst = [
[self._dataGridView1.Rows[i].Cells[0].Value, self._dataGridView1.Rows[i].Cells["Recubrimiento"].Value]
for i in range(self._dataGridView1.Rows.Count)
if self._dataGridView1.Rows[i].Cells["Recubrimiento"].Value is not None
]
self.Close()
# Lista de elementos y valores de recubrimiento actuales
lst_Elements = UnwrapElement(IN[0])
# Obtener valores de recubrimiento actuales en los elementos los cuales se deberan de mostrar por defectos una vez se inicie la ejecucion del codigo
Recu_actual = []
for e in lst_Elements:
para = e.get_Parameter(BuiltInParameter.CLEAR_COVER_OTHER)
recubrimiento = None
if para is None:
recubrimiento = "Error"
else:
idd = para.AsElementId()
if idd.IntegerValue == -1:
recubrimiento = "Sin asignar"
else:
rec = doc.GetElement(idd)
nom = rec.get_Parameter(BuiltInParameter.COVER_TYPE_NAME).AsString()
recubrimiento = nom
Recu_actual.append(recubrimiento)
# Obtener todos los valores posibles de recubrimiento en el documento
todos_recubrimientos = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_CoverType).ToElements()
recu_valores = [r.get_Parameter(BuiltInParameter.COVER_TYPE_NAME).AsString() for r in todos_recubrimientos]
form = FormSetCover(lst_Elements, Recu_actual, recu_valores)
form.ShowDialog()
OUT = form.pairLst
Add the DataGridViewComboBoxColumn
after the DataGridView generation
Following the recommendation, I have placed the line of code but it has returned an error and at the same time you can see that the “Coating” columna has not moved.
did you remove this one?
The DataGridViewComboBoxColumn
(self._ComboBoxValue
) can only be added once (in SetCellComboBoxItems
method)
as an alternative, you can also try WPF + MVVM
1 Like
Good day
Could you recommend how I can learn from scratch to work with WindowsForm and IronPython so I can see what things I can do or what you would recommend. I am very interested in creating this type of windows and even much more personalized and advanced ones.