How to add to ContextMenuStrip and ToolStrip same ToolStripButtons? - c#

I have tool bar in my app and context menu with the same options, so I want to
add ToolStripButtons to both ContextMenuStrip and ToolStrip, unfortunately I can't do this.
Even when I add manually items to both it shows only on one.
For now I have buttons in tool bar:
I want something like this. I want this options to be one, because I will be often enable and disable this buttons and finally there is one option so why two buttons?

This is a common problem and I've found the easiest solution is to place the 'shared' code inside a MenuFeature class that inherits from ToolStripMenuItem.
You still have to create 2 instances of this class, but each instance is very lightweight and only has code for any differences between the 2 usages (i.e. the ContextMenu item might use ToolStripItemDisplayStyle.ImageAndText, while the ToolStrip item might use ToolStripItemDisplayStyle.Image).
This allows common code to exist only once inside your custom MenuFeature class, but still allows changes local to each usage of this menu item.
If you wanted to automatically synchronize properties like Enabled/Visible/etc, you could maintain a static collection of all instances inside the constructor, and then update all the items using events like EnabledChanged/etc. I would recommend against this, however, as I've found different instances of the same menu 'feature' often need their own state - but this is getting out of scope on this Question, those interested in how I've managed items can comment on this answer or PM me.

Related

C#: Reset Controls in a Panel (WinForms)

What is a quick way to reset all the Controls inside a panel to their initial states (Compile-time state)? I have TextBoxes, RadioButtons, ComboBoxes, and CheckBoxes to reset. I'd like them to reset to the values when the program first ran. I'd like a solution that does not involve looping or recursion mainly because I don't want to reimplement the same thing over again when I start witha new project. I'm simply finding a set of methods to call that will do the job. Are there any?
Your controls have no compile time state, because state is a runtime concept.
I think you mean you want controls re-initialized to the state as shown on your property sheets. This state is applied by the generated code located in InitializeComponent, so to re-apply that state, you could just call it again.
The only problem is InitializeComponent also wires up events, and you probably don't want to do that twice. You could possibly work around this by deregistering all of your events before calling it, or by deduplicating the invocation list afterward (see this answer).
I don't recommend any of this. The best approach would be to write your own method that sets the properties the way you want them, one by one. Sometimes ya gotta write code.

Best way to add "dynamic" controls?

My program will prompt the user for a number, i.e. 25. The program will then start the "main form" with 25 controls (textbox). The 25 (or whatever number) of textboxes (or whatever control) will need to be formatted evenly. I will also need to be able to retrieve the text (or another property if I use another control) in order, from left to right and up to down. What is the best method of approaching this?
Using WPF MVVM. In a .XAML file, create a DataTemplate with the DataType of a ViewModel that will provide the binding for your TextBoxs, lets call this the TextboxViewModel. Then using a ItemsControl element with an ItemsSource of TextboxViewModel. You'll be able to instantiate as many TextBoxs as you want and be able to get the result by browsing through your list of TextboxViewModel.
Supposing you are using Windows Forms here.
Dynamically create the X controls and add them to the Controls collection of your form. To ease the access to them you can store their reference in a List and set some event handlers too, depending on your needs. You just need to calculate their positions while you add them.
If WinForms, this is exactly what the FlowLayoutPanel is for. Just add the controls to it and they will arrange themselves automatically, wrapping down to the next row as needed. As Mihai already suggested, you could also keep reference to those controls in a List.
Another option would be to use a TableLayoutPanel. It's a little more difficult to learn and use, but is much more flexible and powerful.

add the same control several times on different parents

I'm trying to add a panel on two different panels in this way:
_formMain.panel3.Controls.Add(_formMain.panel1);
_formMain.panel4.Controls.Add(_formMain.panel1);
What I obtain is that panel1 is added only to panel4 and it is removed from panel3.
It seems that the latest "Add" overwrites the others "Add". Is it true?
Why? How can I add the same panel to some differents controls?
Thank you
Your title says it all:
There is only one control and it can only be in one place, read it can only have one parent.
Therefore, if you change the Parent or Add it to another Control's Controls collection, which is ecxactly the same thing, it will disappear from the previous place.. So while Add doesn't sound like it, it amounts to a Move.
If you need more controls you need to create more controls! And of course they will be different Controls, with different properties and contents..
You can have more than one control show the same content if you keep them synch'ed. One prime example with automatic synchronizing would be two DataGridviews, both with the same DataSource. For other content, like Text or Images the syn'ching is up to you!
You may think about writing a clone function, that can create a deep copy but you will still have to do the syn'ing. This may be codeable as well, depending on the details.. Or you could make it into a UserControl and add fresh instances of it.

Creating Settings view in a WPF application

This question must have been solved multiple times by many people, however after several hours of research I still haven't found what I'm looking for.
What I have is a ExportSettings.settings file with a bunch of settings (bools, strings, ints, etc) and I want to create a View for them. In order to do it I've created a simple window in which I've placed standard buttons as OK, Cancel and Close and linked them to a KeyDown event to let the user accept/cancel using Enter/Escape.
I've created in XAML the needed Checkbox, TextBox, etc, for my settings. When the ExportSettingsView class starts, in its constructor I read my settings and assign the value for each control. In past I bound them directly but that unables the cancelation of changes, so I discarded it. When the user clicks OK button I assign, again, code-behind each value for each settings. If he clicks Cancel no assignment is done and the window just closes.
I would like something like EditableObject for my settings to avoid this ugly looking way of making my SettingsView.
Some of the things I'm looking for are:
Being able to put some comments in my settings would be nice (ToolTip)
Autogeneration of controls using reflection?
Avoid creating custom settings class (and the work of saving and reading everytime the application starts/shutsdown)
Break you problem up into parts to use MVVM, create your window and bind it to another class (ViewModel), this class will have properties on it that reflects the data in your settings file. this class also has to implement INotifyPropertyChanged. It can also implement EditableObject if you want, but frankly it isn't needed.
Hook you buttons up to Commands on your VeiwModel so that when the user hits save, it writes its properties to the settings file.
In this instance:
Window is your View
The new class is your ViewModel
Settings file is your Model
This will allow you to cancel changes, just dont write to your settings file when the user hits cancel.
The biggest point is that you DONT bind to your properties settings directly.
If you want auto generated fields for the view youll have to use a property grid, but with MVVM, your view is decoupled from you model so changing from things like textbox and such to a propertygrid would be easy.
When you do a search for MVVM, dont be fooled by people using a lot of terminology, MVVM is a very simple concept, it boils down to three classes, your View (xaml), View Model (what the view binds to) and Model (your data), THATS IT! good luck
I think you need something like this http://wpfdataform.codeplex.com/
And if you use ReSharper you can easily generate wrapper class for your settings
.NET already supports very nice tool for saving application and user variables. http://msdn.microsoft.com/en-us/library/aa730869(v=vs.80).aspx
It has to be saved explicitly so it might suit you very well. You can check what type the variable is and create a suitable control.

Menu Strip usercontrol that adds items to form at design time

My goal is to emulate the Smart tag already on the menustrip in visual studio that inserts the common menu items.
I'd like to have the user be able to select the item they want from a drop down (I have that already using a UITypeEditor) and then have the items created just like they normally would be at design time (part of the form's components with their creation code in the .Designer.cs file).
The best I have been able to do is to have the menustrip control create the items and add them to it's Items collection. The problem is that the items can't be manipulated further at design time. The menu containing them is actually 'locked'. For the user to add more buttons they would have to do it dynamically at run time.
Is my goal possible and if so could some one point me in the right direction?
I'm not positive, but I think you need to interact with the IComponentChangedService and inform it that your menu has changed. It's been a while since I've written design time support for controls.
In your designer:
IComponentChangeService changeService = (IComponentChangeService)GetService(typeof(IComponentChangeService));
Actually
I think it is the DesignHost you need check out this:
IDesignerHost designHost = (IDesignerHost)GetService(typeof(IDesignerHost));
designHost.Container.Add(...)
I believe you have to add your component to it to manage it.

Categories