Show/hide different custom tabs, individually - vb.net

I have my custom Ribbon tabs and I want to show or hide some of them upon given event. But I want to show/hide them individually, so the tabs should not be dependent on each other or anything like that.
I've been trying the examples from this documentation. and this one but no success.
This is the ribbon XML for the tabs:
<tab id="t1" label="CustomTab" getVisible="GetVisible" tag="xtab">
<!-- some other elements -->
</tab>
<tab id="t2" label="CustomTab_2" getVisible="GetVisible" tag="xtab_2">
<!-- some other elements -->
</tab>
and the VB code:
Private isVisible As Boolean = False
Public Sub GetVisible(control As Office.IRibbonControl, ByRef returnedVal As Boolean)
returnedVal = isVisible
End Sub
Private Sub RefreshRibbon(Tag As String)
ribbon.Invalidate()
End Sub
Public Sub show_xtab(ByVal control As Office.IRibbonControl)
isVisible = True
Call RefreshRibbon(Tag:="xtab")
End Sub
Public Sub hide_xtab(ByVal control As Office.IRibbonControl)
isVisible = False
Call RefreshRibbon(Tag:="xtab")
End Sub
Here I'm trying just with one of them, to make at least that one to work (and then I'm gonna take care of passing the Tag attribute dynamically). But this does not work.
However, if I change the GetVisible method to the following:
Public Function GetVisible(control As Office.IRibbonControl)
Return isVisible
End Function
it will work, but both of the tabs simultaneously. And I want to control them separately.
Any suggestions or tutorials ?
Update: tried some solution from suggestions from comments
XML is still the same. VB code:
Public MyTag as String
Sub GetVisible(control As Office.IRibbonControl, ByRef visible As Boolean)
If control.Tag Like MyTag Then
visible = True
Else
visible = False
End If
End Sub
Private Sub RefreshRibbon(Tag As String)
MyTag = Tag
ribbon.Invalidate()
End Sub
Public Sub show_xtab(ByVal control As Office.IRibbonControl)
Call RefreshRibbon(Tag:="xtab")
End Sub
Public Sub show_xtab_2(ByVal control As Office.IRibbonControl)
Call RefreshRibbon(Tag:="xtab_2")
End Sub
but still no success...

Okay, it seems pretty stupid and I don't know why it works like that, but the solution is the following - I just changed GetVisible from Sub to Function and removed the visible argument, so I directly return True or False, like this:
Public Function GetVisible(control As Office.IRibbonControl)
If control.Tag Like MyTag Then
Return True
Else
Return False
End If
End Function

The correct callback signature procedure type is Sub and If you remove "As Boolean" from the GetVisible callback signature it works as expected.
Signatures here: https://learn.microsoft.com/en-us/previous-versions/office/developer/office-2007/aa722523(v=office.12)?redirectedfrom=MSDN

Related

Changing Picture Box, BackgroundImage from an user control using another user control

I have some buttons from User Control(UserCtrl2) and want to dynamically change UserCtrl1,PictureBox BackgroundImage. From my code below, UserCtrl2 PictureBox BackgroundImage property did changed but winform is still showing the previous BackgroundImage.
I have tried the following methods,
me.refresh in UserCtrl1, still nothing happen.
Not sure how to implement {Get and Set} or dispose function.
Thanks in advance for any advise or reference.
Here is my code for UserCtrl1:
Public Class UserCtrl1
Public Sub UserCtrl1_Task(LEDno As UShort, LEDState As Boolean)
Select Case LEDno
Case 0 : Exit Sub
Case 1
If LEDState Then
PicBox_A.BackgroundImage = My.Resources.ResourceManager.GetObject("Blue_ON")
Else
PicBox_A.BackgroundImage = My.Resources.ResourceManager.GetObject("Blue_OFF")
End If
End Select
End Sub
End Class
Here is my Code for UserCtrl2:
Public Class UserCtrl2
Private ButtonClick(4) As Boolean
Private Sub Btn_A_Click(sender As Object, e As EventArgs) Handles Btn_A.Click
Dim InputControl = New UserCtrl1
If Not ButtonClick(0) Then
ButtonClick(0) = True
Btn_A.BackgroundImage = My.Resources.ResourceManager.GetObject("Switch1_ON")
InputControl.UserCtrl1_Task(1, True)
Else
ButtonClick(0) = False
Btn_A.BackgroundImage = My.Resources.ResourceManager.GetObject("Switch1_OFF")
InputControl.UserCtrl1_Task(1, False)
End If
End Sub
End Class

VBA CommandBarButton does not run code OnAction

Once the button is pressed it does not perform the subroutine defined OnAction method.
I have checked all the Security options in Access are enabled and have written the same code in different ways.
I have tried to run a function with the OnAction method instead.
Private Sub Check_Status_Click()
Dim cmdBAR As CommandBar
Dim cmdButton1 As CommandBarButton
Set cmdBAR = CommandBars.Add(, msoBarPopup, False, True)
Set cmdButton1 = cmdBAR.Controls.Add(msoControlButton)
cmdButton1.Caption = "Dale"
cmdButton1.OnAction = "Dale"
cmdBAR.ShowPopup
'Clean
Set cmdBAR = Nothing
Set cmdButton1 = Nothing
End Sub
Public Sub Dale()
MsgBox "hola"
End Sub
I dont get any error, just it is not doing anything even the menu shows up.
Actually OnAction subroutine needs to be
public sub
in public module
So you should change your code to something like this:
...
cmdButton1.Caption = "Dale"
cmdButton1.OnAction = "Dale"
cmdBAR.ShowPopup
...
And place your sub into some public module:
Public Sub Dale()
MsgBox "hola"
End Sub

Show VBA userform with variables in userform name

I am doing a PPT where I need to click buttons to show various Forms.
I have created a public function in the main module.
Public Function ShowForm(FormName As String)
Dim oneForm As Object
For Each oneForm In UserForms
If oneForm.Name = FormName Then
oneForm.Show
End
End If
Next oneForm
End Function
And used it in the button below:
Private Sub NextPage_Click()
ShowForm ("SU0" & qlist(cntr))
cntr = cntr + 1
End Sub
But the function does not work. Did I miss anything or is there a better way of doing this?
Solved
Google is the key...
I have changed the function in the module and everything works fine now.
Public Function ShowForm(FormName As String)
Dim oneForm As Object
Set oneForm = CallByName(UserForms, "Add", VbMethod, FormName)
oneForm.Show
End Function
Note that in order to handle multiple userforms, the "ShowModal" property of those forms needs to be set to FALSE.

Refactor for Maintainance

Public Sub ButtonVisibilityOnTab()
Select Case ctl.Parent.Name
Case "tabGeneral"
ctl.btnAdd.Visible = True
Case "tabSecond"
ctl.btnAdd.Visible = False
Case "tabThird"
ctl.btnAdd.Visible = False
Case Else
ctl.btnAdd.Visible = False
End Select
End Sub
How can I optimize/refactor the above code.
I have an app with 3 tabs and a common user control between them. I want to enable the visibility for a add button I have only the first tab.
How can I optimize the code so that in the future if can avoid another case if the user control is reused.
Should I pass the bool value with the tab control name to accomplish that.
or would an array of controls be logical as a pass in value for the method..
AS your code is written, it can be simplified to
Public Sub ButtonVisibilityOnTab()
ctl.btnAdd.Visible = (ctl.Parent.Name.ToLower().Equals("tabgeneral"))
End Sub
Or more generically,
Public Sub ButtonVisibilityOnTab(CompareTo as String)
ctl.btnAdd.Visible = (ctl.Parent.Name.ToLower().Equals(CompareTo.ToLower()))
End Sub
If you have a lot of these statement to do, you could create a setting class.
Class Settings
Public Property CanAdd As Boolean
End Class
This class would be inside each tabs and each tabs would set their own values. Then, your button visibility function would look at the current tab settings.
Public Sub ButtonVisibilityOnTab()
ctl.btnAdd.Visible = ctl.Parent.Setting.CanAdd
End Sub
You could then implement on all your tab an interface that handle the settings. Your function would then look like.
Public Sub ButtonVisibilityOnTab()
ctl.btnAdd.Visible = CType(ctl.Parent, ISomeInterface).Setting.CanAdd
End Sub
This is what worked for me, and I started passing the control Name as a parameter.
Private Sub ButtonVisibilityOnTab(controlName As String, blnShowOrNot As Boolean)
If _ctl.Parent.Name = controlName Then
_ctl.btnAdd.Visible = blnShowOrNot
Else
_ctl.btnAdd.Visible = Not (blnShowOrNot)
End If
End Sub

Catch event from item stored in a dependency property

How do you catch an event from an object raised in a dependency property?
For example, normally I'd write something like this
Public Property foo1 as foo
get
return _foo
end get
set (value as foo)
_foo = value
end set
end property
Private WithEvents _foo as foo
Public Sub Foo_Handler() Handles _foo.SomeEvent
'Do soemthing
End Sub
However you can't declare a dependency property as WithEvents. Any ideas
Here is the solution I came up with. I don't really like it and it doesn't feel right, but it works. If someone has a better solution please provide it as an answer. To provide a little more information about my use case, I have a dialog named OkCancelDialog. It's basically just a placeholder to present content to the end user. When the user clicks Ok, the Save method of ISaveView is called and conversely when the Cancel button is clicked, it calls the Cancel method. The problem I ran into is that the save method usually has to save the item asynchronously. Originally I had marked the save method as a function that returned a boolean (which closed the dialog if true), but the problem was that if something went wrong during the save, the OkCancelDialog would already be closed. So now, I call the Save method and provided everything saves properly in the View, it raises the event CloseView, which I then capture in the OKCancelDialog to close the dialog.
I would love to hear other options for accomplishing this.
Interface ISaveView:
Public Interface ISaveView
Sub Cancel()
Sub Save()
Event CloseView()
Event HasChanges()
End Interface
Class with DP:
DP:
Public ViewProperty As DependencyProperty = DependencyProperty.Register("View", GetType(ISaveView), GetType(OkCancelDialog), New PropertyMetadata(Nothing, New PropertyChangedCallback(AddressOf OnViewChanged)))
CLR Property:
#Region "View"
Public Property View As ISaveView
Get
Return DirectCast(GetValue(ViewProperty), ISaveView)
End Get
Set(value As ISaveView)
SetValue(ViewProperty, value)
End Set
End Property
Public Sub OnViewChanged()
_view = View
OnPropertyChanged("View")
End Sub
Private WithEvents _view As ISaveView
Private Sub View_HasChanges() Handles _view.HasChanges
okButton.IsEnabled = True
End Sub
Private Sub View_CloseView() Handles _view.CloseView
Me.Close()
End Sub
#End Region