Author Topic: Function to add a button to a panel  (Read 139 times)

0 Members and 1 Guest are viewing this topic.

ysr2014

  • Mosquito
  • Posts: 2
Function to add a button to a panel
« on: December 02, 2017, 08:11:00 pm »
here it is a general function to add a button to a panel

usage :
Code - vb.net: [Select]
  1.        yac.Rib.TabAdd("Design", True)
  2.        yac.Rib.PanelAdd("Concrete", "Design")
  3.        yac.Rib.BtnAdd("Beam_Design", "Concrete", "Design")
  4.  

the code above adds the Tab and the Panel successfully
but when implements the BtnAdd autocad crashes

what is wrong in my BtnAdd function

please help

Code - vb.net: [Select]
  1.       ' TabAdd
  2.        ' ********
  3.        ' add a tab to the ribbon system
  4.  
  5.        'yac.Rib.TabAdd("Yasser", True)
  6.  
  7.        Public Shared Function TabAdd(TabName As String, Optional IsActive As Boolean = False) As RibbonTab
  8.  
  9.            'declare a ribboncontrol object
  10.            Dim ribCntrl As RibbonControl = ComponentManager.Ribbon
  11.  
  12.            'create a ribbontab
  13.            Dim ribTab As New RibbonTab()
  14.  
  15.            'set a few properties
  16.            ribTab.Title = TabName
  17.            ribTab.Id = TabName
  18.  
  19.            'add the tab to the ribbon
  20.            ribCntrl.Tabs.Add(ribTab)
  21.  
  22.            If IsActive = True Then
  23.                ribTab.IsActive = True
  24.            End If
  25.  
  26.            Return ribTab
  27.  
  28.        End Function
  29.  

Code - vb.net: [Select]
  1.       ' PanelAdd
  2.        ' *********
  3.        ' add a panel to a tab
  4.  
  5.        ' yac.Rib.TabAdd("Yasser")
  6.        ' yac.Rib.PanelAdd("Nana", "Yasser")
  7.  
  8.        Public Shared Function PanelAdd(PanelName As String, TabName As String) As RibbonPanel
  9.  
  10.            Dim ribCntrl As RibbonControl = ComponentManager.Ribbon
  11.  
  12.            'create the panel source
  13.            Dim ribSourcePanel As RibbonPanelSource = New RibbonPanelSource()
  14.            ribSourcePanel.Title = PanelName
  15.  
  16.            Dim ribPanel As New RibbonPanel()
  17.            ribPanel.Source = ribSourcePanel
  18.  
  19.            ' find tab by TabName
  20.            Dim ribTab As RibbonTab = ribCntrl.FindTab(TabName)
  21.  
  22.            If ribTab IsNot Nothing Then
  23.                ribTab.Panels.Add(ribPanel)
  24.            End If
  25.  
  26.            Return ribPanel
  27.  
  28.        End Function
  29.  

Code - vb.net: [Select]
  1.        Public Shared Function BtnAdd(BtnName As String, PanelName As String, TabName As String,
  2.                                      Optional Img16 As String = "", Optional Img32 As String = "") As RibbonButton
  3.  
  4.            Dim ribCntrl As RibbonControl = ComponentManager.Ribbon
  5.            Dim ribTab As RibbonTab = ribCntrl.FindTab(TabName)
  6.            Dim ribPanel As RibbonPanel = New RibbonPanel
  7.            Dim ribSourcePanel As RibbonPanelSource = New RibbonPanelSource()
  8.  
  9.            'ribPanel = ribTab.FindPanel(PanelName)
  10.            'ribSourcePanel = ribPanel.Source
  11.            ribPanel = ribCntrl.FindPanel(PanelName, False)
  12.            ribSourcePanel = ribPanel.Source
  13.  
  14.            Dim btn As RibbonButton = New RibbonButton
  15.            btn.Text = BtnName : btn.ShowText = True
  16.            btn.CommandParameter = "NETLOAD "
  17.  
  18.            If Img16 <> "" Then
  19.                btn.Size = RibbonItemSize.Standard
  20.            End If
  21.  
  22.            If Img32 <> "" Then
  23.                btn.Size = RibbonItemSize.Large
  24.            End If
  25.  
  26.            ribSourcePanel.Items.Add(btn)
  27.  
  28.            Return btn
  29.  
  30.        End Function
  31.  

MickD

  • Gator
  • Posts: 2970
  • I don't need a job, I need Money!!
Re: Function to add a button to a panel
« Reply #1 on: December 02, 2017, 09:12:28 pm »
I don't know the intricacies of VB.net but you shouldn't need to create a new control when you are assigning and existing control to it later.
Code - vb.net: [Select]
  1. Dim ribSourcePanel As RibbonPanelSource    '= New RibbonPanelSource() shouldn't need to create a new one here??
  2. ...
  3. ribSourcePanel = ribPanel.Source
  4.  
"A language that doesn’t have everything is actually easier to program in than some that do."

        — Dennis M. Ritchie

n.yuan

  • Bull Frog
  • Posts: 240
Re: Function to add a button to a panel
« Reply #2 on: December 03, 2017, 08:56:28 am »
A few things:

1. Have you run debugging that steps through the code in BtnAdd() method where the exception occur? If you did, you would easily find out the direct cause of the exception.

2. Since you said the crash occurs in BtnAdd(), here is the cause I could guess: you should use

ribPanel = ribTab.FindPanel(PanelName)  ''Which you commented out for unknown reason(s)

instead of

ribPanel = ribCntrl.FindPanel(...)

because RibbonControl.FindPanel() ONLY finds panels on ACTIVE RibbonTab! So, in your case, if the custom ribbon tab - "Design" is not the active one, the code would return a null, so the code for adding button would raise exception.

3. If I were you, I would ALWAYS test if the Tab/Panel/Button existence before adding, because it is possible that your code would handle WorkSpaceChanged event to make sure your custom ribbon tab stays when user shift between WorkSpace during the same AutoCAD session. That is, I'd have some custom ribbon generating code run on AutoCAD startup and run whenever Workspace changes, thus the rationale of testing existence before creating ribbon items.

4. As MickD correctly pointed out, in BtnAdd() method, you DO NOT declare something as "New RibbonXXX" unless you know they do not exist and you need to create them. That is, as I  said, you try find out if they exist and only "New" them, when necessary.

ysr2014

  • Mosquito
  • Posts: 2
Re: Function to add a button to a panel
« Reply #3 on: December 03, 2017, 05:44:00 pm »
Thanks Friends .... I finally detected the problem

first of all, this code of functions is inside a separte library project, and I'm testing these functions in a test project refrencing the library.

the first problem
**************
AutoCAd crashes because I didn't include this Import in the test project :

Code - vb.net: [Select]
  1. Imports Autodesk.Windows

even if I already imported in the library

2) thanks MickD for your hint, and I Modified in the code

3) thanks n.yuan for your hints, really usefull

4) I added the id property for all 3 functions, TabAdd, PanelAdd, and BtnAdd

the code will be in test class as :

Code - vb.net: [Select]
  1. Imports Autodesk.Windows
  2.  
  3.        yac.Rib.TabAdd("Yasser", True)
  4.        yac.Rib.PanelAdd("Nana", "Yasser")
  5.        yac.Rib.BtnAdd("Load dll", "Nana", "Yasser", "NetLoad ")

and in the class Rib as :

Code - vb.net: [Select]
  1. Namespace yac
  2.  
  3.    Public Class Rib
  4.  
  5.        ' TabAdd
  6.        ' ********
  7.        ' add a tab to the ribbon system
  8.  
  9.        'yac.Rib.TabAdd("Yasser", True)
  10.  
  11.        Public Shared Function TabAdd(TabName As String, Optional IsActive As Boolean = False) As RibbonTab
  12.  
  13.            'declare a ribboncontrol object
  14.            Dim ribCntrl As RibbonControl = ComponentManager.Ribbon
  15.  
  16.            'create a ribbontab
  17.            Dim ribTab As New RibbonTab()
  18.  
  19.            'set a few properties
  20.            ribTab.Title = TabName
  21.            ribTab.Id = TabName
  22.  
  23.  
  24.            'add the tab to the ribbon
  25.            ribCntrl.Tabs.Add(ribTab)
  26.  
  27.            If IsActive = True Then
  28.                ribTab.IsActive = True
  29.            End If
  30.  
  31.            Return ribTab
  32.  
  33.        End Function

Code - vb.net: [Select]
  1.        ' PanelAdd
  2.        ' *********
  3.        ' add a panel to a tab (by its name), as a RibbonPanel
  4.  
  5.        ' yac.Rib.TabAdd("Yasser")
  6.        ' yac.Rib.PanelAdd("Nana", "Yasser")
  7.  
  8.        Public Shared Function PanelAdd(PanelName As String, TabName As String) As RibbonPanel
  9.  
  10.            Dim ribCntrl As RibbonControl = ComponentManager.Ribbon
  11.  
  12.            'create the panel source
  13.            Dim ribSourcePanel As RibbonPanelSource = New RibbonPanelSource()
  14.            ribSourcePanel.Title = PanelName
  15.            ribSourcePanel.Id = PanelName
  16.  
  17.            Dim ribPanel As New RibbonPanel()
  18.            ribPanel.Source = ribSourcePanel
  19.  
  20.            ' find tab by TabName id
  21.            Dim ribTab As RibbonTab = ribCntrl.FindTab(TabName)
  22.  
  23.            If ribTab IsNot Nothing Then
  24.                ribTab.Panels.Add(ribPanel)
  25.            End If
  26.  
  27.            Return ribPanel
  28.  
  29.        End Function

Code - vb.net: [Select]
  1.        ' BtnAdd
  2.        ' *******
  3.        ' add a button to a panel (by its name), in a tab (by its name) as a RibbonButton
  4.  
  5.        'yac.Rib.TabAdd("Yasser", True)
  6.        'yac.Rib.PanelAdd("Nana", "Yasser")
  7.        'yac.Rib.BtnAdd("Load dll", "Nana", "Yasser", "NetLoad ")
  8.  
  9.        Public Shared Function BtnAdd(BtnName As String, PanelName As String, TabName As String, cmd As String,
  10.                                     Optional Img16 As String = "", Optional Img32 As String = "") As RibbonButton
  11.  
  12.            Dim ribCntrl As RibbonControl = ComponentManager.Ribbon
  13.            Dim ribTab As RibbonTab = ribCntrl.FindTab(TabName)
  14.            Dim ribPanel As RibbonPanel
  15.            Dim ribSourcePanel As RibbonPanelSource
  16.  
  17.            ribPanel = ribTab.FindPanel(PanelName)
  18.            ribSourcePanel = ribPanel.Source
  19.  
  20.            Dim btn As RibbonButton = New RibbonButton
  21.  
  22.            btn.Text = BtnName
  23.            btn.ShowText = True
  24.            btn.CommandParameter = cmd ' "NETLOAD " for example
  25.            btn.Id = BtnName
  26.  
  27.            If Img16 <> "" Then
  28.                btn.Size = RibbonItemSize.Standard
  29.            End If
  30.  
  31.            If Img32 <> "" Then
  32.                btn.Size = RibbonItemSize.Large
  33.            End If
  34.  
  35.            ribSourcePanel.Items.Add(btn)
  36.  
  37.            Return btn
  38.  
  39.        End Function
  40.  
  41.    End Class
  42.  
  43.  
  44. End Namespace

still working on the code to complete Image and Tooltip ... and adding checks for existing

Tested and Working Good

Thanks alot my friends  :smitten:
« Last Edit: December 03, 2017, 05:50:40 pm by ysr2014 »

n.yuan

  • Bull Frog
  • Posts: 240
Re: Function to add a button to a panel
« Reply #4 on: December 04, 2017, 09:43:36 am »
Thanks Friends .... I finally detected the problem

first of all, this code of functions is inside a separte library project, and I'm testing these functions in a test project refrencing the library.

the first problem
**************
AutoCAd crashes because I didn't include this Import in the test project :

Code - vb.net: [Select]
  1. Imports Autodesk.Windows

even if I already imported in the library

...

still working on the code to complete Image and Tooltip ... and adding checks for existing

Tested and Working Good

Thanks alot my friends  :smitten:

Good to hear your code worked. However, I do not believe missing "Import Autodesk.Windows" would be a possible cause of code crashing:

Without that "Imports...", your code in the library project would either not build, or build successfully. That is, the "Imports..." is only for the code compiler to correct qualify classes in the code. Or we can say, it is somewhat meant for programmers' convenience to not having always type a class name

Dim ribItem as RibbonItem

AS

Dim ribItem As Autodesk.Windows.RibbonItem