I am making a plugin who changes depending on a text file.
Is it possible to change a Ribbon button name without restarting the software Revit ?
Yes, it is possible.
You typically construct your panels and buttons during ExternalApplication Startup.
If you store as properties/fields the buttons or other UI elements you need to change, it is possible to change those objects at runtime from your commands or other events.
Related
Is there a way to display the projects settings in a form inside the application?
I have added a Menu Item called setting, Now when that is clicked I want a small form to popuo with the applications setings.
Is there a quick way to do this that just displays the settings as you would see them in Visual Studio? Or do I have to manually fetch the settings and display them?
If I need to manually do it. Which type of form must I use so that it will appear inside my main form?
I think you'll manually need to collect them and display them. To display on an area inside your main form you'll want to use a UserControl and place your created UserControl on your main form.
Take a look at PropertyGrid control. It's the one what VS uses itself to edit properties of things (aka settings). Displaying things is pretty easy: add PropertyGrid to a form and assign object to it propertyGrid.SelectedObject. You will be able to see and edit properties of that object (in case of configuration settings this will be a configuration class instance I assume) almost right away! Tuning, adding localization, etc are not trivial tasks, but there are plenty of tutorials.
Otherwise, you could possibly use TableLayoutPanel with 2 columns: labels and respective texboxes (or other edit controls, to example, NumbericUpDown for int values), rows are autosized. But then you will have to add label and textbox for each setting yourself, as well as write some code to implement getting/setting of each configuration setting.
I wrote my first C# program a while ago. It got somewhat big. My .settings file has over 20 different parameters - booleans, sizes, strings, ints. I'd like to provide users with a GUI to change them during runtime instead of editing the app.exe.config file which is somewhat advanced and confusing.
I'm very inexperienced with C# but seems like there should be a better way than for me to manually create a form, drag in labels, inputs, checkboxes, radio buttons, and manually handle all gui events and what happens when values get changed and whatnot. Building this gui by hand seems like a lot of work.
How do you guys handle the settings of a C# app? Can't I generate something from the XML?
In WinForms applications you can add a control to a Form and then click the (PropertyBinding) under (ApplicationSettings) in the Property box.
The dialog allows you to bind properties of the control to a parameter in the config file. It is an extra step during design but it must be done.
These settings will end up in the user config file (I strongly advise against the application config file for this)
You will have to provide the user with a way to specify these settings by either:
having the user edit the config file - very dangerous because it is very easy to mess that up.
allowing the user to manipulate the UI (drag-drop) and save the settings from code. - a lot of work to prevent the user painting himself in a corner.
a separate/standalone designer application that combines 1. and 2.
In WPF you can use DataGrid or ListView for your task. However, if you are inexperienced with C# or WPF, it is maybe faster to do the settings form by hand.
I've inherited a project that has been modified in a way that is beyond me to undo. Every single control on the form is not modifiable in the designer except through the Properties window and each control has an icon in the area below (see image) in the section usually reserved for non-visible items (e.g. DataSource). How do I undo this and return the designer to a usable version without wiping it all out and starting over?
Could the controls be locked? I have run into legacy code in which the programmers have locked every single control, meaning you cannot move or resize them in the designer. If so, select them all and change the Locked property to false (you should also see a padlock in the designer when you select them, if they are locked.
If not, well maybe you can create a new dialog/form and copy the controls unto it and see if that clears things up. Another trick could be to add a second instance of the user control(s) to see if the newly added control works as expected. If so, go through the code and point all events/logic to the new control (tedious yes, but may work).
Also, you can never edit individual sub-controls of a user control in the designer for the form/control where you instantiated the user control. You must go to the designer of the user control to edit individual (sub)controls of a user control.
If the Infragistics controls are shown in the Component Tray, than there might be version differences. What you could try is to open the licenses.licx file and remove the content from there. Do you have an Infragistics controls installed on your machine? Are there any difference after setting the "Specific Version" property of the Infragistics assemblies to "false"?
Is this happening only in your existing project or the same behavior is reproducible in a new project as well?
You have to load the dll that contains the controls you can't modify in the designer.
the steps are:
right click in the ToolBox in visual studio designer (on General for example).
select Choose Items...
after a while vs load items press browse and select the dll
interested than the componet should appear in the grid. Do this for
all the dll that contains the controls you are interested.
-Make sure you have checked the component (use filter text box if you
have a lot of component loaded).
press ok.
Now you should be able to move controls in designer.
I have also seen behavior this when a user control or form is incorrectly flagged as a 'Component'.
Some manual hacking of the .csproj file may be the answer then. Open the project file in a text editor, and find the references to your control. If you find a subtype defined as:
<Compile Include="MyControl.cs">
<SubType>Component</SubType>
</Compile>
The forms designer will interpret it as such. You can change the 'SubType' to 'UserControl' to fix it.
How does one set a ribbon button in a Word add-in to be enabled when a document is loaded and disabled when no documents are loaded, just Like most of the built-in buttons?
Can one bind a global flag to the "Enabled" property of the button, or is it more complicated than that? I know I could create a timed loop that checks for changes in Application.Documents, but I'm looking for something "cleaner" if possible.
I've already looked at Disable Own Word 2007 Add-In If No Document Loaded and other related questions.
There are several ways to handle this.
first, you can create a publicly exposed function that returns true or false for the enabled state of your button (however you want to determine that), you then define your ribbon xml to point to that function for the Enabled property getter. If you're dealing with an IExtensibility based addin, then this is the way you'd have to go.
If you're dealing with VSTO, then define your ribbon button in the ribbon designer and make it DISABLED by default.
Then, during the STARTUP event, hook the WORD object, specifically the NEWDOCUMENT, DOCUMENTOPEN and WINDOWACTIVATE events.
In the event handler code for each of those events, enable or disable your buttons as applicable depending on which event fired and which document was activated at the time.
Use the DocumentChange event instead. Hook up will be something like this:
Globals.ThisAddIn.Application.DocumentChange += new EventHandler(OnDocumentChange);
And the Handler
void OnDocumentChange()
{
this.myButton.Enabled = wordApp.Documents.Count > 0;
}
Interesting, my VSTO Contrib project (http://vstocontrib.codeplex.com/documentation) has some features which make ribbon management simpler.
The cleanest way is to use my ribbon factory, but the project will need to be updated to disable buttons if there are no viewmodels to query for the status of the button. In fact it is a scenario I havent really covered.
You have 3 parts an add-in is interested in, the view (window), the context (the document) and the ribbon. VSTO Contrib means you get a view model per context, and it manages/abstracts the ribbon and view so it appears you have a ribbon per context, and it tells you the current active view (for multiple windows showing same document scenarios).
The missing part is if there is a ribbon, but no contexts and no viewmodels, it should invalidate that ribbon control and disable it. It should be a pretty simple change, email me if you are interested in giving VSTO Contrib's RibbonFactory a spin and I can make this change for you.
Pre .net I was using MFC, ON_UPDATE_COMMAND_UI, and the CCmdUI class to update the state of my windows UI.
From the older MFC/Win32 reference:
Typically, menu items and toolbar buttons have more than one state. For
example, a menu item is grayed
(dimmed) if it is unavailable in the
present context. Menu items can also
be checked or unchecked. A toolbar
button can also be disabled if
unavailable, or it can be checked.
Who updates the state of these items
as program conditions change?
Logically, if a menu item generates a
command that is handled by, say, a
document, it makes sense to have the
document update the menu item. The
document probably contains the
information on which the update is
based.
If a command has multiple
user-interface objects (perhaps a menu
item and a toolbar button), both are
routed to the same handler function.
This encapsulates your user-interface
update code for all of the equivalent
user-interface objects in a single
place.
The framework provides a convenient
interface for automatically updating
user-interface objects. You can choose
to do the updating in some other way,
but the interface provided is
efficient and easy to use.
What is the guidance for .net Windows Forms? I am using an Application.Idle handler in the main form but am not sure this is the best way to do this. About the time I put all my UI updates in the Idle event handler my app started to show some performance problems, and I don't have the metrics to track this down yet. Not sure if it's related.
I've found it easiest to have the menu item event handler spawn a background thread that disables the menu item, does the work, and then re-enables the menu item. That way, the UI is available to handle other UI requests, and I don't need to poll for when the operation is complete.
I usually include logic that prevents more than one operation that uses the same resources to happen simultaneously. This means creating a function to disable/enable all similar resources at once. e.g. I might only allow 1 file operation to happen at a time, so I would create a function to disable/enable all the menu items associated with file operations and call it from every one of those menu items.
Just change their property, e.g.
obj.Enabled = true;
or
obj.Enabled = false;
The property of that object will automatically call .Invalidate() or .Refresh() for you, so the control should be repainted automatically.
If you want to do a BIG task which would block the UI for multiple seconds, it's worth using Threads + Delegates.
AFAIK, in the standard .NET System.Windows.Forms world, this functionality is not available out the box.
This problem can be answered in a few ways. The links below are useful resources:
•OnUpdate equivalent
•ActionLists for Windows forms
•Command UI Updating Windows Forms in C#