I have (quite basic) question about RibbonX callback functions.
I coded some macros with VBA packed in VBA modules and created a ribbon tab by using Office RibbonX Editor.
I created an XML with the editor like so...
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
<ribbon startFromScratch="false">
<tabs>
<tab id="maintab" label="My Macros">
<group id="g_general" label="General">
<button
id="btn_toggle_confidential"
label="Toggle Confidential"
onAction="Toggle_Confidential_Text"
size="large"
imageMso="MailMergeUpdateLabels"
supertip="Toggles the visibility of the 'confidential' tag in the master and in the title layout." />
...
...for all functions that I want available in the ribbon, such as e.g. :
Sub Toggle_Confidential_Text()
If Has_Confidential_Text() = False Then
MsgBox "ATTENTION! There is no confidential tag in the slide master!"
Exit Sub
End If
' etc...
End Sub
Everything works fine and as expected!
In the "callbacks viewer" of the ribbonX editor I see this:
'Callback for btn_toggle_confidential onAction
Sub Toggle_Confidential_Text(control As IRibbonControl)
End Sub
My question is:
How does this accurately connect the button to the function in my code module? Or is this just some simplified display of the "routing" that is done under the hood?
Is the IRibbonControl parameter automatically passed, even though my own subroutine declaration doesn't mention it?
Can I (or how can I) access the IRibbonControl parameter in my subroutine to interact with the ribbon element? Do I need to redesign my approach and wrap my subroutines or can I just access the parameter, because it's implicitly passed?
It should not work as you say it working... If the callback Sub does not contain control As IRibbonControl it should return an errror: "Wrong number of arguments or invalit property assignment". At least, this was happening when I tried creating the callback Sub without control As IRibbonControl parameter.
For a button control, no parameter is automatically passed. If you make the recommended declaration you can use 'Contol.ID' to have the pressed button name. 'Label' in fact...
You can, but not only knowing the control label. Besides label, it also offers Context and Tag...
Related
I have a ribbon xml where I want to add something similar as in the picture. I tried create a button and connect the menu to the button but I never got the arrow indication there is a underlying menu. I have no faith at all in that button is the correct element to use. Been googling for hours now and would be happy if anyone can send me in some kind of direction. There is no problem for me to add the element in the context menu, the problem is the dynamic menu linked to the first element.
The control type you're looking for is dynamicMenu
Here is the ribbon XML:
<dynamicMenu id="mycustomid" label="My custom label" getContent="GetMyCustomContent" />
And the code:
public string GetMyCustomContent(IRibbonControl control)
{
return "<menu xmlns=\"http://schemas.microsoft.com/office/2009/07/customui\">"
+ "<button id=\"anotherid\" label=\"another label\" onAction=\"DoWhatever\"/>"
+ "</menu>";
}
public string DoWhatever(IRibbonControl control)
{
}
I would like to enable select buttons on a custom ribbon after a user registers. I am having problems getting back to the ribbon load command.
Sub Button_Enabled(control as IRibbonControl)
BtnRegistration.Enabled = False
BtnSetup.Enabled = True
BtnBuild.Enabled = True
End sub
You can't modify ribbons directly, but you can set a getEnabled callback and return a boolean. Here is a C# example, should be simple enough to do the same in VB.
Ribbon XML:
<button idMso="ClearFormatting" getEnabled="HasRegistered" />
Code:
public bool HasRegistered()
{
return User.IsRegistered;
}
Once you have completed registration, invalidate the ribbon.
ribbon.Invalidate(); // all controls
ribbon.InvalidateControl(id); // only one control
I have ASPxGridView to view a list of records. From the view, I create a delete column and want it to show a delete button whenever the record does have a satisfy condition. The code below:
<dx:GridViewCommandColumn Caption="Delete" VisibleIndex="1" Width="30px"
meta:resourcekey="GridViewCommandColumnResource1">
<DeleteButton Visible="True">
</DeleteButton>
</dx:GridViewCommandColumn>
So I focus on the Visible attribute of DeleteButton. The condition must return a boolean value so it knows when to show and hide the delete button. Below is an example how to implement this:
<DeleteButton Visible='<%# ShowHide(Eval("Active")) %>'>
</DeleteButton>
in VB Code:
Protected Function ShowHide(Active As Boolean) As Boolean
Return Active
End Function
So the function need to return a True value if Active is True, and False value if Active is False. In other words, I do trigger a function in code behind on every record to make it show the delete button if record does have a satisfy condition. But I got an error message in the end:
Parser Error Message: Databinding expressions are only supported on objects that have a DataBinding event. DevExpress.Web.ASPxGridView.GridViewCommandColumnButton does not have a DataBinding event.
I stuck there and don't know other way to do this. Please help me with this.
After a night to research on this, I have find a new way to solve this issue:
This block of code from aspx file within an ASPxGridView:
<dx:GridViewCommandColumn Caption="Delete" VisibleIndex="1" Width="30px"
meta:resourcekey="GridViewCommandColumnResource1">
<DeleteButton Visible='True'><!--TRI - 20160329 Please make sure the Visible attribute always True-->
</DeleteButton>
</dx:GridViewCommandColumn>
From the code behide, I implement an initial method to handle a trigger on DeleteButton:
Protected Sub xgv_CommandButtonInitialize(sender As Object, e As DevExpress.Web.ASPxGridView.ASPxGridViewCommandButtonEventArgs) Handles xgv.CommandButtonInitialize
If e.ButtonType = DevExpress.Web.ASPxGridView.ColumnCommandButtonType.Delete Then
If sender.GetRowValues(e.VisibleIndex, "Active") = True Then
e.Visible = False
End If
End If
End Sub
The method will handle the DeleteButton by checking the Active value on Command Button Initialize. If the Active is True, it will hide the DeleteButton and vice versa.
You could either handle the ASPxClientGridView.CustomButtonClick Event as shown here : Link or Place your custom control into GridViewDataColumn.DataItemTemplate : Link
I'm using the following code:
Dim Reply As DialogResult = MessageBox.Show("GOT IT!")
If Reply = DialogResult.OK Then '...`
When I click the Close button (red "X" in corner) the condition looking for DialogResult.OK still evaluates to true and when I check the Reply variable's value at runtime after clicking the close button it is 1 {OK}.
From the documentation on MessageBox Class it says:
Displays a message window, also known as a dialog box, which
presents a message to the user. It is a modal window, blocking other
actions in the application until the user closes it. A MessageBox can
contain text, buttons, and symbols that inform and instruct the user.
While I find the documentation on DialogBoxes a little convoluted and confusing, it appears to me (and i could be bery wrong) that the Close button should by default set the return to IDCancel which, I must assume is somehow parsed by the MessageBox class into DialogReturn.Cancel.
So why does MessageBox not show the return form the close button as DialogResult.Cancel??
This is all very confusing to me because it seems the MessageBox class is not consistent with other forms from within the same Systems.Windows.Forms namespace.
For instance, if we look at the documentation from the Form Class's .DialogResult method, it specifically tells us the return from the close button is DialogResult.Cancel:
When a form is displayed as a modal dialog box, clicking the Close
button (the button with an X in the top-right corner of the form)
causes the form to be hidden and the DialogResult property to be set
to DialogResult.Cancel.
As already stated in the comments above, you could get IDCancel result when clicking the Close Red Button, only if you add a MessageBoxButtons enum that include the Cancel option For example MessageBoxButtons.OKCancel and others.
The MessageBox.Show method is indeed a wrapper around the WinApi MessageBox function. You could see this wrapping looking at the reference sources
The behavior of MessageBox.Show is different from the link that you have pointed. That one is relative to the WinForm engine and of course the behavior of the WinForm Form class is totally managed by the library to handle the scenarios presumed for a WinForm class.
In the WinApi documentation you could find a subtle reference in the section about the Return value where they talks about the behavior when the cancel button is present. Then trial and error confirms this assumption.
You need to pass in MessageBoxButtons as an override that includes a cancel button so like MessageBoxButtons.OKCancel.
Dim message As String = "GOT IT!"
Dim caption As String = "Fancy Caption"
Dim Reply As DialogResult = MessageBox.Show(message, caption, MessageBoxButtons.OKCancel)
If Reply = DialogResult.OK Then '...`
If you dont want the caption than skip it but you'll still need a comma, like:
MessageBox.Show("GOT IT!",,MessageBoxButtons.OKCancel)
See here for full enumeration of options for MessageBoxButtons.
I've created my own ribbon toolbar tab with a few buttons. I can add text and similar actions to the document I'm working on. Now I want to add a button that will save the document I'm working on without using the Word save button because I want to set some of the parameters.
Every example I found showed how to save a document that was started by my code (Dim MyDoc As New Word.Application) but when I use such syntax from the ribbon button - ActiveDocument is saying that there is no active document.
Any ideas?
ThisAddIn.vb contains:
Protected Overrides Function CreateRibbonExtensibilityObject() As _
Microsoft.Office.Core.IRibbonExtensibility
Return New MyRibbon()
End Function
MyRibbon.xml is very basic (taken from an MS sample)
<group id="ContentGroup" label="Content">
<button id="textButton" label="Insert Text"
screentip="Text" onAction="OnTextButton"
supertip="Inserts text at the cursor location."
/>
</group>
The new document that you have created is not going to be of type Word.Application. Your ribbon/add-in is running in a current Word.Application context.
If this is indeed what you are doing, you should be creating instances of Word.Document, and saving those.
What exactly is the code you are using to create the document, the ribbon, and save your changes?