C# Winforms - Prevent a control from stealing focus when added programatically - c#

I have a bit of an odd question.
My situation is as following:
I have a form, It contains several user controls that in turn contains either other user controls or other basic controls such as TextBox, RichTextBox and such.
As part of the logic when editing the text boxes, I create another control programatically and inform the form about it. Other controls on the form may react in turn and create more controls.
Trouble is, These controls steal focus from my control when they are created and added to the form/other controls.
Is there a way to prevent my control from losing focus while that happens?

Maybe you should include in the logic, the tab indexes first, and when you add the control, set the tab index to the last tab index + 1, your job would be easier, if you set the tab order first on the controls, and set the constant to the last tab index at design time, see here,:
private const int LAST_TAB_INDEX = 5; // an Example
private int lastTabIndex = LAST_TAB_INDEX;
private void AddControl(){
// Set up your control
Control ctl = new Control();
// ....
ctl.TabIndex = lastTabIndex;
this.Add(ctl);
this.lastTabIndex++;
}
You can see from the example how the tab index is incremented, in that way, it will prevent
the controls from stealing the focus...
Hope this helps,
Best regards,
Tom.

Controls can't accept (steal) focus unless they are visible and enabled. Have you tried creating the controls with one or both of these as false, and then turning them on when appropriate?

Related

Recommended way to manipulate User Control panels into a Windows From

I just started working with Visual Studio C# and to be honest I didn't fully understand what happens when we chose to hide a form or a user control.
My intuition tells me this hide/show method is kind of "inefficient" way to get an user through all the functions of my app.
So I am asking you guys if there is another workaround to "load" user control parts in a form.
Right now my main_menu form has all the user control objects placed on the form, but hidden, and I am using buttons to show them.
Is there a better way to achieve the same result? (I was thinking of a workaround like having an empty panel where I can load the User Control - not sure if possible)
Thank you!
You can create the controls on the fly and add them to or remove them from the Controls collection. On the class level, define this field
private Control _currentPanel;
You can use a more specific type here, if you are deriving all your panels from a common base type.
Then change the panel with
// Remove previous one.
if (_currentPanel != null) {
Controls.Remove(_currentPanel);
}
// Add new one
_currentPanel = new MyNewPanel();
//TODO: possibly set the panels Docking property to Fill here.
Controls.Add(_currentPanel);
In the example I am working with the form's Controls collection; however, you might have to use the Controls collection of some container control holding the panel.

Tags in WinForms TextBox

I want to create a textbox on a WinForms form, where the user cannot input text directly. Instead, the content of the textbox should only be "bubbles" (with a "delete" button), showing a text value.
I'm struggeling to find the correct term for this kind of control/behaviour. It should look a bit like the "Tags"-field on StackOverflow when creating a new question.
Are there any existing controls/settings that allow such behaviour? (I have DevExpress if that helps)
Sorry for the vague question, if i knew better terms for what i'm looking for, i'd probably find something...
Instead of a textbox, the container for your bubbles should most likely be a Panel.
You can style it as needed, set the border, background color, etc.
If you don't want to manually position the "bubbles" inside it, use a FlowLayoutPanel. It will automatically put it's children controls in a flow.
Check out the properties of the control to specify how you want controls to be laid out.
The individual bubbles can also be Panels or other container controlls, so that you can add a label and a button (or image to serve as a button) to each.
You might even extend the panel class to automatically add a label and a delete button to each.
something like this (please note this is more like pseudo code. I wrote it up of the top of my head here, some adjustment may be needed)
Public Bubble : Panel {
Public Bubble(string text) {
Label title = new Label { Text = text };
Controls.Add(title);
Button delete = new Button { Text = "Delete" };
Controls.Add(delete);
//also hook up events here, ie delete.click+= whatever
}
}
You can further extend the custom class for your specific needs.
Set styles on the button and label as needed to achive the look you want.
Don't forget to hook up events such as mouse over, button click, etc.
Then just fill the FlowLayoutPanel with these custom controls and you should be good to go

How to force a focus on a control in windows forms

I am trying to focus a "search" textbox control in my windows forms application. This textbox is inside a user control, which is inside a panel which is inside a windows form (if it is important).
I tried 3 methods which I could find:
// 1
this.ActiveControl = myTextBox;
// 2
myTextBox.Focus();
// 3
myTextBox.Select();
Neither of them seems to work. I mean for example when I try the first one, active control is really set to myTextBox, but when I try to write something on keyboard, textbox doesn't accept it and I have to first click inside the textbox to get focus. This is same with all of the methods.
Am I missing something?
Ok, finally found the answer:
As I said my textbox is inside user control which is inside panel which is inside a form.
When I need my user control I add it to panel. To get focus on my textbox I have to firstly focus my user control so something like this:
In my top Form:
panel.Controls.Add(myUserControl);
myUserControl.Focus();
and then in my user control:
myTextBox.Select();
Note that if I used: myTextBox.Focus() it wouldn't work (don't know why). Also if I used myUserControl.Select() instead of myUserControl.Focus() it wouldn't work either.
This seems to be the only combination which works.
You could do these logic steps to set your control to be the focus:
your_control.Select();
your_control.Focus();
Enjoy! :)

Indexing into Controls Collection on Tab Control

I have a C# Forms tab application. Each TabPage has a menu on the left (Outlook style navigation panel), and a Panel on the right for content.
If I want the content panel for tab page 0, how would I go about fetching it? I'm a bit stumped because I don't know how to index into the controls collection on a tab page. The following is underlined in red, so I believe its wrong.
Panel panel = tabControl.TabPages[0].Controls["Panel"];
EDIT: remove Window in Panel sub question. It will be moved to a separate question.
Sorry about the beginner questions. I'm a C/C++ guy with lots of MFC time, and C# UI is a bit frustrating at the moment.
foreach (Control control in tabControl1.TabPages[0].Controls)
{
// if (control.Name == "panel1")
}
You can always call this recursively on control.Controls to find a control in any hierarchy. control.Name can be used to find your specific control.
You can't show a Form, inside a Panel. You could create Custom Control where you can add your functionality and add that control to a Panel.
in order to create a new form for example you need to create a variable of what ever form that it is you want to create.
example
Form2 frm2 = new Form2();
frm2.Show();
if you want to show that form in the panel then the panel would be the Owner keep in mind the difference between Owner and Parent
please paste what ever code you have so far and we can suggest the necessary changes
Finally, how does one display a Window in a Panel? - you don't want to do that. If you want a window and a panel to share a piece of UI functionality, create a user control with all the the functionality and then you can place it in a form or in a panel.
A possibility to encapsulate complex UI content is to create a UserControl. This way you can create a reusable piece of complex UI you can basically add as a "blob" inside a form.
The reason why
Panel panel = tabControl.TabPages[0].Controls["Panel"];
is underlined red is because the Controls collection returns a Control which might be a Panel but also might be something else. So you need to cast it:
Panel panel = tabControl.TabPages[0].Controls["Panel"] as Panel;
if (panel != null)
{
// got a panel here so do something
}
Also: MSDN has some good resources - you should make use of it.

Move contents of Form when a Control is re-Located

Let's just say that I have many controls on my Form, and when a User clicks on one of them, its height will expand. This means that, currently, when this clicked-control expands, other controls below it will become overlapped by the expanded control.
But what I want to happen, is for each Control below the expanded control to slide down, so that they are below the expanded control again.
I know how to handle sliding, but I just don't know how to make every control except for one move everytime a given control is moved.
Any help at all is greatly appreciated, thank you!
This is what I was thinking:
void newOrderReceived(object sender, EventArgs e)
{
foreach(Control OrderNotificationBox in OrdersPanel.Controls)
{
if(OrderNotificationBox is NotificationBox) // Checks to see if the control is a NotificationBox
{
// Add my code to slide controls down.
}
}
}
But... How do I know if the control is below the expanded control?
Is this how I should go about changing the location of all controls below the expanded control?
Edit: Just had a thought, to check to see if a NotificationBox is below the Expanded NotificationBox, see revised code below:
void newOrderReceived(object sender, EventArgs e)
{
foreach(Control OrderNotificationBox in OrdersPanel.Controls)
{
if(OrderNotificationBox is NotificationBox) // Checks to see if the control is a NotificationBox
{
if(OrderNotificationBox.Location.Y <= ExpandedNotificationBox.Location.Y + ExpandedNotificationBox.Size.Width)
{
// Add my code to slide controls down.
}
}
}
}
But would this be sufficient? Currently, this is working, so I guess I just answered my own question. But, isn't there a better way to do this? A more elegant/efficient way?
Here's a sample of how it should look:
FlowLayoutPanel provides you with dynamic layout where you can resize any control in it and all below controls will slide automatically. There are many strategies to using groups/columns of flow layout panels to be able to achieve the desired look for the whole form. Some googling will reveal some of these.
For instance in the form above, resizing the button1 control simply flows all the below controls to further down on the form. You can try that at the design time also. Drop the form a flow layout panel, drop 3-4 control in the container and start experimenting..
For each expandable content use Panel.
Dock your panels one under another (Use panel1.Dock = DockStyle.Top. For the very bottom panel use panel1.Dock = DockStyle.Fill).
Place your child controls inside of each expandable panel, set inner controls' Anchor properties accordingly.
When you expand one panel, the rest of the panels will adjust automatically. You don't need to code for this. You will only change Height of a panel that you currently expand.
What you need is some kind of 'ExplorerBar' functionality. There are several control libraries that offer that, and I found the article here on the CodeProject that has it for free.

Categories

Resources