I have a ContextMenuStrip on a DataGridView. After realizing that calling cm.FindForm() results in null, I added the context menu to the grid's ContextMenuStrip property, but that doesn't help.
Is there some other setting that I'm missing so that the context menu's FindForm() will return the form?
Note: I added the context menu via the visual studio designer by dragging it to the form. Also the main menu (a MenuStrip) doesn't show this behavior, its FindForm() returns the form properly.
Edit: For Hans (why I do things the way I do)
I used to have all code in one long Form1.cs, but that is obviously hard to maintain. I found that separating all code into a framework that is a separate class for each component, that then references the other classes as needed by injection easier to maintain and follow.
For those components that are not controls, I pass the form the component belongs into the constructor, but for those components that are controls, I found the FindForm() method to be a shortcut. The base class of the framework uses the FindForm(). Therefore each component has access to the form via a Form property.
Now I'm finding that the context menu control is not getting, as said, its Parent control set, and therefore FindForm() isn't working.
Related
Setup:
I have created a Form that I wish to have serve as the base from which I will inherit other forms. This base form serves as a "template" of sorts, but it also provides a good deal of functionality related to the structure, as well as the interrelation of all of the controls provided.
A primer for the images that follow... The top info-colored bar is a custom control inherited from ToolStrip. The bottom strip is another custom, again inherited from ToolStrip. The left white block is a TreeView and the right block is a TabControl (having deleted all TabPages from it...I intend for these to be added in the inherited forms).
Image of base form in designer:
Image of inherited form in designer:
Clearly, the only difference is that when I open the inherited form, I get a little box icon superimposed over each control, and when I click them, I get the padlock telling me I cannot edit.
The problems:
All controls on the inherited form are locked. I have researched the issue of visual inheritance, and as far as I can tell, I'm not using any controls that expressly do not support it, as this link suggests there are. In this Q&A, Hans suggests changing the modifier on those controls, which I have done. In fact, I tried both Public and Protected, all to no good result.
I am stumped.
This is a technical restriction in the designer, it is specific to the SplitContainer control you are using. And some other ones. The trouble-maker is the ISupportInitialize interface.
Controls use this interface when they can't afford the properties of the control to be assigned in an arbitrary order. The designer helps when it sees that the control implements this interface, it calls the BeginInit() method when it starts assigning properties, EndInit() when it is done. The control uses these methods to delay the side-effect of property assignments, the EndInit() method makes them effective. Important for SplitContainer, the minimum sizes of the panels also affect the splitter position.
Perhaps you can see the rub, the InitializeComponent() method in the base form class has already called ISupportInitialize.EndInit(). So modifying properties again in the derived form class is unlikely to turn out well. The designer protects the control from this by locking it.
Very inconvenient, there is no simple workaround. If modifying the SplitContainer in the derived form class is a hard requirement then you'll have to give up on inheriting it or write the code by hand in the derived class constructor.
In my C# WPF .NET 4.0 application, I have a listbox containing user control items. What I want is to call some functions from these user controls to the parent form.
Item user controls have binding to the listbox via view model class.
What do you propose.
Thank you,
You can bind a command to your user control the same way as it would be a parent view. Then you can process this command in the appropriate view model.
I'm not entirely clear on what you're trying to do, but it sounds like you have a bunch of user controls and you want those controls to be able to call methods on the containing Window instance.
From inside your controls, you can use the following to get hold of the Window instance:
Window parentWindow = Window.GetWindow(this);
Note though that you can't do this from the control's constructors, because during the constructor the control won't yet have a parent window and the above will return null. The best place to do this would be from the control's Initialized or Loaded events.
I have a simple winform app with textbox.
I didnt assigned any context menu to text field and "it uses" standard one. I desire to add some new items to textbox's standard context menu. But I cant obtain it for modification, if be more clearly I didnt know how to obtain HMENU native object.
ContextMenu property of my textbox equals null so I suppose that menu appers within textbox defaul windProc routing. It there a way to get the default context menu or get a copy of it?
Thanks in advance!
Depending on any plug-ins you're using, it may be easier, and more understandable, to create a custom control that derives from TextBox and defines a "default" contextual menu. Then, change all TextBoxes in your solution to be your custom control instead. Failing that, if you have a common window ancestor, set up some initialization code that assigns a given ContextMenu to all controls in the form's hierarchy of type TextBox. Instead of plugging in to low-level Windows hooks, you're using what the framework gives you to accomplish the same end, and your posterity doesn't have to know how Windows handles contextual menus at a message-passing level in order to alter this behavior.
I have an mdi child form as a dockable content in my application and I want to disable/enable a listbox in it from the parent form depending on a certain event. I thought this would be simple as:
_child.listBox1.Enabled = false;
But it doesn't seem to disable it. _child is an object reference of the mdi child form btw. Why does it not work and how can I fix this?
_child probably refers to a different instance of the child form.
Make sure that _child refers to the same instance that you called Show() on.
Can't you create a function on your MDI child which would disable the listbox, you could call from the MDI parent?
I guess that here listBox1 is private (which is the default if you have constructed your form using VS designer)
Although it works, exposing the control of a form as a public property is considered a bad design practice.
Suppose that at some point in the future, you will have to change the internal ListBox into some other type, such as ListView, in order to add some functionality.
In this scenario, if you create a method called DisableList on the form, you will only have to change one place in code, to update the way the list should be disabled.
But if you choose the method of writing code such as _client.listbox1.Enabled = false;, you will have to go through all the pieces of code that touch the ListBox, and update them.
A very important principal in design is to avoid exposing the internal implementation details of class to those that have to use it. In this case, you will benefit if the parent form won't have to know that the list is implemented as a ListBox.
I have the same question, but the answer to use a UserControl will not do. I also need to create a control container that I can add other controls to at design time so I can add it to yet another container (Splitter Panel) which is not avaialable to me at design time (plugin architecture). When I make a User Control, it is missing the design time support and all I get are icons when I drop controls onto this surface.
Do I need to add all the design time support myself, or is there something I am missing that has this for me?
You will have to use either a Form or UserControl to accomplish any forms design within the designer.
I have often created controls that I need to manipulate en masse. Start with a UserControl, then add a panel that fills the UserControl. This is your base panel that you will fill with all of your controls. I then save as a duplicate control and simply remove the UserControl and leave the panel as the public UI control which is then instanced. If I am making changes, I can go back to the original UserControl, make changes, add code, etc - rinse and repeat.