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.
Related
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 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.
I've got windows form app I'm developing, and my client wants a TreeView on the left with nodes that when clicked allow their users to work in detail screens on the right. The simplest approach was to create panels which are disabled until the appropriate node is clicked. However, this app is growing and way too much of it is living in the main form.
I'm wondering if it is possible to have one form per node that will open and expand into the detail area on the right, and then close when I am done with it. That way I don't have a single monolithic form, however I am not sure of how to go about that.
Anybody have any insight into how to do something like that?
Thanks.
You should try using UserControls.
Basically, each UserControl is a form (more or less) that you can add to your main form just like you would any other control.
I would inherit from Panel for each page, attach an instance of each Panel-derived object to the Tag property of each TreeView node, and display that (Dock=Fill) when a node is selected.
You can use split controls and load the forms right side but needs to arrange it correctly. As #codethis mentioned, usercontrol is best enough to handle these as their code is written separately. Just you need to pass the parameter (from node selection).
You may need to multiple user controls and place them in your form according to your screen changes.
We use the ContentControl and other containers stuff in WPF. I need the notification with the new child control is added to the container. What is the best way to get the newly created control within parent?
The ContentControl only contains a single child which is attached via the ContentControl.Content property. You can hook the ContentControl.OnContentChanged to discover when the value of this property is updated.
The cleanest way is to derive from those control and override the methods that report the changes you are interested in. For example derive from ContentControl and implement OnContentChanged. This approach may not appeal to you.
If you want to detect changes in the child or children of controls without deriving from them, you can observe that such changes will affect the layout and so you can hook the LayoutUpdated event. The problem with this approach is that you need to keep track of the children that were previously added yourself by inspecting Child or Children looking for changes. You also have to be careful not to hang onto references to former children lest you create a memory leak. But it can be done.
I have programmed c# application i will post screenshot. In this main form is 3 buttons which opens different forms. Now i decided to modify this application I want to Make one main form with strip menu which will open this forms. I used this code but i don't like or i'm doing something wrong. I don't like because there is child controls(minimize, maximize, close) in parent (please see second picture ):
Please advice me something. Is MDI good for such job? Thanks!
Sell sell = new Sell();
sell.MdiParent = this;
sell.Dock = DockStyle.Fill;
sell.Show();`
So my problem is that parent form is not filling when i open child form this is creen how to make that it parent form was filled with child form
Seeing your latest edit, I assume the reason that your child form's content doesn't fill the screen even when it's maximized is because your content/layout is not flexible.
Wherever you've placed the controls during Design Mode is where they're going to end up at run time, regardless of how big or small you make the window. If the window is too small to contain all of them, they'll either be covered up or you will see scrollbars. Alternatively, if the window is made larger than necessary, you'll see a lot of empty space.
The way around this is either to set the Dock and Anchor properties of your controls, which causes them to expand and compress to fit the layout of their containing form. You could also place your controls inside a TableLayoutPanel or FlowLayoutPanel control to help manage their layout.
As far as the question you appeared to be asking originally, I still can't tell if you're opposed to the way an MDI application looks, or if you simply don't understand how to correctly implement it. The clarification comment you offered actually makes things less clear to me—you posted a code snippet, but didn't explain what it means. As I wrote in a comment, there's no (non-hackish) way to show a form that doesn't have minimize, maximize, and close buttons (setting the FormBorderStyle property to "None" does this, but I think this is a silly solution that simply allows you to use the wrong control for the job—it won't behave like a form, the user won't be able to move it around like a form, etc. so why use a form?).
If you truly want to have a single application window with changing content in the center, you should create a series of UserControls. You can lay out each user control with the necessary child controls, just like you would with a form (using the fluid layout techniques I discussed above), add each user control to your main form, set each control's Dock property to "Fill" (so that they fill the entire viewing area), and then write code to simply swap out the currently visible user control in your main form's viewing area. The advantage of using a UserControl versus something like a Panel is that you consolidate all of your code into a single control, much like you would with a Form. You could use a tab control, but if you don't want to show any indication that there are multiple forms (which is what your aim appears to be), this would also be the wrong control for the job.
If you literally want to open child forms inside your main form, as your question title indicates, you should indeed be using MDI. If you don't understand how to do this, you'll need to clarify your question further.
Set MDI Container property to true for your parent form. It will help.
Set
FormBorderStyle = None
for your child forms