Create a control that has menu's characteristic? - c#

Can I create a control that has 2 menu's characteristic:
Do not take form's focus on clicking.
Automically disappear when clicking outside.
I intend to draw it manually, but I realise I can't draw outside of form's border like system menu.

You are describing the ToolStripControlHost, which can contain any control you want. Paired with the ToolStripDropDown, and you have a very effective custom drop down control that will not take focus from the main form, and will close when clicked outside of it:
Dim toolDrop As New ToolStripDropDown()
Dim toolHost As New ToolStripControlHost(myControl)
toolHost.Margin = New Padding(0)
toolDrop.Padding = New Padding(0)
toolDrop.Items.Add(toolHost)
toolDrop.Show(Me, New Point(0, 0))
Whatever myControl is, sometimes you have to set the MinimumSize of it equal to the size of the control. There are events you can handle for the ToolStripDropDown such as, Opening and Closing.

what kind of control? is it a CommandButton? if so, you can set Allow Focus Property to False.

Related

c# toolstrip doesn't dock under menustrip

I have a menustrip that I create using the forms designer. I then want to programmatically add a toolstrip toolbar UNDER the menustrip. The reason is that this toolbar is a set of tools that I add as a plugin to the main application. As such, when the plugin is loaded, I create the toolbar.
When I manually add the toolstrip to the form using the forms designer, the toolstrip is correctly positioned under the menustrip. However when I add it programmatically, it snaps to the topmost part of the form, above the menustrip. Here's the code I use to programmatically add the toolstrip:
stereoBar = new ToolStrip();
stereoBar.Anchor = (AnchorStyles)(AnchorStyles.Top | AnchorStyles.Left);
//y location is set to 22, the width of the menustrip
stereoBar.Location = new System.Drawing.Point(0, 22);
stereoBar.Dock = DockStyle.Top;
stereoBar.Name = "StereoToolbar";
stereoBar.Text = "Stereo Plugin Toolbar";
stereoBar.ShowItemToolTips = true;
stereoBar.GripMargin = new Padding(2);
Controls.Add(stereoBar);
Is there anything simple I am missing here?
Thanks in advance!
As described also in this answer, when docking controls in a form the order in which you add them to the form matters; i.e. when adding multiple controls that all dock to the top, the last control that gets added will be the topmost.
So, because you add your toolstrip programmatically and your menu strip via designer, the designer code gets executed first thus having the menu strip always at the bottom.
I think there are three ways out of the dilemma:
First approach
As Hans Passant pointed out, the easiest way to get things into the right order would be to simply call
stereoBar.BringToFront();
right after you added it to the forms' controls.
Second approach
To circumvent this you could also also add the menu strip programmatically and do this after you added the tool strip.
Third approach
Another way out may be to add another container to the form (Panel or groupbox for example) via designer that also docks to the top that simply just functions as a placeholder where you add your tool strip to (so you do not add to the form directly anymore)

Is it possible to add more than one panel in same location

i'm using telerik control.
So i want to ask,
In winforms application ,Is it possible to add more than one panel in same location and display one at a time just like show/hide property.
Make sure you have placed all panel control in same container or form. then you can use Visible property to show and hide panel. BringFront and SendToBack function will be used to bring panel on top or send it to back. If you have placed any panel in another panel then that will be disappeared when you Hide parent panel. So, Make sure all panels' parent control must be same. To determine the parent control simply select that panel and press escape key to select their parent.
private void LoadPanels()
{
panel1.Location = new Point(10,10);
panel2.Location = new Point(10,10);
panel3.Location = new Point(10,10);
panel4.Location = new Point(10,10);
panel5.Location = new Point(10,10);
VisiblePanel("panel1");
}
private void VisiblePanel(string panelName)
{
string[] panels = new string[]{"panel1","panel2","panel3","panel4","panel5"};
for (int i=0;i<panels.Length;i++)
this.Controls[panels[i]].Visible = (panels[i] == panelName);
this.Controls[panelName].BringToFront(); //Not required you can remove this line.
}
Here's a slightly different approach you might want to consider...
Are you wanting to be able to programmatically select the contents of a rectangular area at runtime, selecting among various controls to display? If so, you could use a custom TabControl which has its tabs (not the pages) hidden.
Then you can select which page is displayed by programmatically changing its SelectedIndex property at runtime.
Doing it like this means that your form editor will show a normal tab control, which allows you to much more easily add the content to each page - but at runtime the tabs will be hidden from the user; they will just see the contents of the currently selected page.
See Hans Passant's answer here for how to create such a custom tab control.
(However, you might also want to override the OnKeyDown for the custom tab control in order to ignore Ctrl-Tab.)

How to prevent usercontrol fill option from extending too far

I have a usercontrol that I'm adding as a control of a main form dynamically. The Mainform is basically empty, except it has a large status bar on bottom.
Problem is, when I set the Dockstyle.Fill option on my usercontrol, the size of the loaded usercontrol extends beyond the statusbar (It fills the entire main form as if the status bar wasn't there).
How do I prevent this behavior? This is an example of how I dynamically load my form
logicForm = new LogicForm();
this.Controls.Add(logicForm);
logicForm.Dock = DockStyle.Fill;
I think you need to set the DockStyle to None and use the Anchor property instead.
Set the anchor to Top,Bottom,Left,Right and size your control to fill all the space up to the status bar.
You should find when you run that the user control will then resize with the form.
I just found the solution
I need to bring the form to front in order to properly dock it if I already have some other controls on the main form:
logicForm.BringToFront();
Found here: http://dotnetref.blogspot.kr/2008/08/using-dock-fill-on-control-when-you.html
-________________________-

How to simulate a drop-down window in WinForms?

i know a Windows Combobox control is nothing but a Textbox and a ListBoxglued together.
i need to simulate the same thing in WinForms. i am trying to figure out Windows window options that must be set to achieve the proper effect.
the drop-down cannot be a child window - otherwise it is clipped to the parent's area
conceptually it must be a pop-up window - an overlapped window
it can be an owned window - An owned window is always above its owner in the z-order. The system automatically destroys an owned window when its owner is destroyed. An owned window is hidden when its owner is minimized.
The best i've managed so far is to create
a borderless (this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None)
topmost (this.TopMost = true)
form that doesn't show in the taskbar (this.ShowInTaskbar = false)
this borderless topmost form contains my "drop-down" control. i "hide" my dropdown when the dropdown form loses focus:
this.Deactivate += new EventHandler(TheDropDownForm_Deactivate);
void TheDropDownForm_Deactivate(object sender, EventArgs e)
{
...
this.Close();
}
This conglomeration of mess works well enough...
...except that "drop-down" takes focus away from the owner form.
And this is my question, what properties should my popup window have?
SW_SHOWNOACTIVATE?
But then how do i hide my drop-down form when it loses focus - when it cannot lose focus?
How do i simulate a combo-box drop-down in .NET?
Note: Don't confuse what you see in the example screenshot with something else. i am asking how to create "drop-down" form in Winforms - the contents can be different than the screenshot above:
Using a ToolStripControlHost and a ToolStripDropDown can achieve the same effect.
From this answer:
Private Sub ShowControl(ByVal fromControl As Control, ByVal whichControl As Control)
'\\ whichControl needs MinimumSize set:'
whichControl.MinimumSize = whichControl.Size
Dim toolDrop As New ToolStripDropDown()
Dim toolHost As New ToolStripControlHost(whichControl)
toolHost.Margin = New Padding(0)
toolDrop.Padding = New Padding(0)
toolDrop.Items.Add(toolHost)
toolDrop.Show(Me, New Point(fromControl.Left, fromControl.Bottom))
End Sub

Could Label get a focus?

I have a one question on my university's test about C#. Could label get a focus? As I can see on MSDN site, all Controls can get a focus, but some of them aren't selectable. So it's seems to me that the right answer is "Label could get a focus, but couldn't be selected". Also Label has a Focus() method. Please, help me understand. Thanx.
Yes there is a Focus() method on Label and yes it is absolutely right it works; but behave differently. let me try to explain
A Label can be associated with some one input control, for instance a label for a user name text field, so there is concept of Associated Control with the label. AssociatedControlID on msdn
So you can associate an input control with a label and whenever label is selected the control passed to the associated input control.
Example here click on Email or Password labels in login box and see what happened, similarly if you call focus method on the label the focus will passed to the associated control.
From the documentation:
A control can be selected and receive
input focus if all the following are
true: the Selectable value of
ControlStyles is set to true, it is
contained in another control, and all
its parent controls are both visible
and enabled.
Since a Label control is not selectable, it cannot receive input focus, even if it inherits a Focus() method from Control. Therefore, the answer is no.
It's easy to findo out if a control's ca get focus. Just read the
.CanFocus
property which is inherited from the Control class.
The Windows Forms controls in the following list are not selectable. Controls derived from these controls are also not selectable. (see MSDN documentation)
Panel
GroupBox
PictureBox
ProgressBar
Splitter
Label
LinkLabel (when there is no link present in the control)
Also:
The Focus method returns true if the
control successfully received input
focus. The control can have the input
focus while not displaying any visual
cues of having the focus. This
behavior is primarily observed by the
nonselectable controls listed below,
or any controls derived from them.
A control can be selected and receive
input focus if all the following are
true: the Selectable value of
ControlStyles is set to true, it is
contained in another control, and all
its parent controls are both visible
and enabled.
If you need a Label-like control that you can focus, just use a TextBox and make it readonly. Set a few other properties (styles, not selectable etc.) and you're done.
You will see that there is a read only property called CanFocus on a label, if you have a look at this property while debugging you will see it is false.
Every control that inherits from Control has the focus method, but that does not mean that it can be focused.
Label does gets the focus but it escalates it to the input field specified in its "for" attribute. Like:
<label for="firstname">First Name</label><input type="text" name="firstname" />
In this scenario if you click on the label it will throw the focus to the input field "firstname" associated with it.
This is a year old, however I had a similar issue as the Op. In my case it was a user control that had a single label (docked at fill) on it (it has other functions behind the scenes - it is a calendar control and pops up a date picker - not the standard one - in either a panel (popunder) or a form (popup)).
The issue there was that UserControls are really intended as containers and resist focus (pushing it off to child controls) - as the label is the only child control, it stops the UserControl getting focus. Using readonly TextBox is a poor substitute as it lacks vertical alignment and must be multiline to size the height.
The reason I add the following as an answer here is because it IS possible (sorry guys who said here it is not) and I found this post and many like it that were little help when I looked. Anyway, the way to do it is to override the Label and set the SetStyle - also the OnPaint to draw a focus rectangle (I manually drew mine as DrawFocusRectangle didn't seem to do anything) - so as below:
internal class SelectableLabel: Label
{
public SelectableLabel():base()
{
SetStyle(ControlStyles.Selectable, true);
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
//ControlPaint.DrawFocusRectangle(e.Graphics, ClientRectangle);
if (!Focused) return;
if (BorderStyle == BorderStyle.Fixed3D)
{
e.Graphics.DrawLines(Pens.CadetBlue, new[] { new Point(1, Height - 1), new Point(1, 1), new Point(Width - 1, 1) });
e.Graphics.DrawLines(Pens.Aquamarine, new[] { new Point(2, Height - 1), new Point(Width - 1, Height - 1), new Point(Width - 1, 2) });
}
else
{
e.Graphics.DrawRectangle(Pens.Aquamarine, 0, 0, Width - 1 , Height - 1 );
}
}
}
I am not concerning myself on whether it is accademically (purist view) right to do so, but that there are valid reasosn to allow an output control (like label) to sometimes gain focus.

Categories