When the TabPage.Hide() doesn't have any effect why is still available?
tcImgBase.TabPages["tabPage3"].Hide();
The general implementation to hide a tab page is to remove it.
Can someone explain the scope of Hide & Show?
The Hide() method just changes the Visible property. It's implemented in the Control class, which is the base class for all Windows Forms controls. That means that all controls have this method and property and it can't be hidden since that's how C# works. However, it's not meaningful for all controls, such as TagPage and, indeed, the MSDN documentation says as much:
This member is not meaningful for this control.
And later:
To hide a tab in a TabControl, you must remove it from the control's TabPages collection.
Both from: http://msdn.microsoft.com/en-us/library/vstudio/y6e1ah1k(v=vs.100).aspx.
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.
When you have a TableLayoutPanel on your Form and you drag a Label into a cell, a few properties are available on the Label control. I think the same construction is used when you drag a Tooltip control on the form.
I'd like to know which design pattern is used to achieve this. Is this the decorator pattern?
What you are seeing are called Extender Providers.
For example, when a ToolTip component is added to a form, it provides
a property called ToolTip to each control on that form. The ToolTip
property then appears in any attached PropertyGrid control.
http://msdn.microsoft.com/en-us/library/ms171836.aspx
I can't think of a well-known pattern that describes how they work, exactly, but the mechanism is simple.
You must implement IExtenderProvider. The WinForms Designer will call CanExtend for each other control on the surface, and your extender can specify if it provides additional attributes for each control.
public interface IExtenderProvider {
bool CanExtend(object extendee);
}
The actual attributes that other controls will be extended are declared using the ProvidePropertyAttribute and a method to provide the value.
No, this is not achieved through a design pattern. These properties are simply the public properties exposed by the control, these properties are added to the control via inheritence, i.e. they sub-class Control. The visual studio designer inspects the class which implements these controls to determine the properties they expose, then provides you with a UI for setting them.
I have a custom user control, onto which I place a button control. I set the access modifier of the button to Public. When I drop the user control onto a form, I see the button, but am not able to select it or edit its properties in the form designer.
Ultimately, I want to create a far more complex custom wizard control, with a content panel, "Back" and "Next" buttons, etc. I have successfully created a content panel to which controls can be dropped into at design time on the main form.
However, I am bulked at not being able to edit nested controls on the user control itself.
When inheriting from a user control, or inheriting from a form, one can typically edit properties of controls whose access modifier is set to "Protected".
What do I need to do to be able to access controls of the custom user control from the designer of the form?
I think you need go to the user control designer view to modify the properties of the button (instead of the form where the user control is placed), since it is nested in the user control.
You can make basic changes to a child control of a user control on a form to the limited extent that you can expose the properties of interest via the parent user control designer and support the property changes at design time. You can make much more complex design time behaviors by writing your own custom designers but that is a potentially difficult to very difficult undertaking.
There is a good reason why it does not work the way you probably think it could and should and if you think about it carefully enough for a while, you will understand why. When you inherit from an object, yes you can change properties etc, but in this case you are creating a new type, so you can modify, add, redefine properties.
But when you drop a user control on a form, you are not creating a new type. You are creating an instance of a type, the user control, that is already defined. To the extent you can modify properties, you are modifying state that must be preserved for that instance. State must not only be persisted, but user controls also often involve painting etc so state changes can also have complex behavioral effects and this is a potentially complicated requirement that cannot be completely generalized.
So there are some modifications that are not possible at all, because they imply modifying the type, and you already have a type, you are only creating an instance. For the rest of the possible range of modifications that are ultimately state based, the platform only supports so much of the total possible state management.
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've come across the feature in Visual studio to auto-generate a subclass of a custom control using Add New Inherited User Control.
But I haven't found a clear description on how to e.g create a subclass of Button for instance. Apart from the actual way to do it, I'm also interested if VS provides helpful code-generation for this?
You just create your own class that inherits the Control, that you would like to subclass. For instance:
class BetterButton : Button { ...}
That is the easy part. Now you have the option to override various methods or properties, depending on what you want to achieve with your new Control. It could be anything, really. One thing I often see used is overriding OnPaint to get the control drawn in a custom way; and still getting the behaviour of the original control.
In terms of UserControls, I often see that a "parent" UserControl contains some UI logic and basic UI elements, while the subclassed controls are refinements of the parent for specific use.