In my application I dynamically create buttons and add them to a flow control that is later cleared. I have this on a timer to refresh every X seconds to clear then add buttons. This is all being done on the main form.
The problem is when I have a child form launched the main form will steal focus every time the controls are added to the flow control.
Here is the code I have that dynamically clears and adds the controls on the main form.
I call this before adding the controls
flw_users.Controls.Clear();
This is what I call to dynamically create/add the buttons to the flow control.
private void DisplayNewMobileUser(string MobileUserName)
{
// Set Button properties
Button button = new Button();
button.Text = MobileUserName;
button.Size = new System.Drawing.Size(171, 28);
button.Name = MobileUserName;
button.BackColor = System.Drawing.Color.White;
button.FlatAppearance.BorderColor = System.Drawing.Color.White;
button.Font = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Bold);
button.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
button.ForeColor = System.Drawing.Color.Black;
button.Margin = new System.Windows.Forms.Padding(0, 1, 0, 1);
button.TextAlign = System.Drawing.ContentAlignment.TopLeft;
button.Click += new EventHandler(MobileUserName_OnClick);
flw_users.Controls.Add(button);
}
Is there a way to add buttons to a flow control with out it always stealing focus ?
Thanks to LarsTech I researched how to properly dispose each control added to flw_users. The main issues was fixed by changing the OnClick event to change focus to a label, which in turn didn't cause the main form to gain topmost every time the controls were cleared and re added. So everytime I clicked a button that button still had focus while the new form appeared.
Thanks everyone !
Here is the code I used to properly clear the controls
private void ClearUsers()
{
List<Control> ctrls = new List<Control>();
foreach (Control c in flw_users.Controls)
{
ctrls.Add(c);
}
flw_users.Controls.Clear();
foreach (Control c in ctrls)
{
c.Dispose();
}
}
Related
I'm trying to create a dynamic flowcontrolPanel and make it visible after adding controls to it. However the problem now is, the controls are added successfully but the panel is not visible on the screen. The below piece of code is a sample which I have tried form my side:
List<object> lstChild = lstFromChild;
//creating an instance for the flowlayoutpanel
FlowLayoutPanel objflowParent = new FlowLayoutPanel();
objflowParent.Name = "flowLayoutParent";
objflowParent.Location = new Point(380,155);
objflowParent.Size = new Size(800, 800);
objflowParent.BackColor = Color.DarkCyan;
objflowParent.BorderStyle = BorderStyle.Fixed3D;
objflowParent.Dock = DockStyle.Fill;
objflowParent.AutoSizeMode = AutoSizeMode.GrowAndShrink;
objflowParent.Size = new Size(300, 30);
objflowParent.SuspendLayout();
//Adding Controls to the flowlayoutpanel
foreach (Control item in lstChild)
{
objflowParent.Controls.Add(item);
}
objflowParent.ResumeLayout(false);
//Tried to hide a datagrid available in the screen to check if it is hiding the panel
dgMainGrid.Hide();
this.Show();
Note: lstChild is the list carried form another form with controls loaded in it.
I made a simple button, but when i click outside of win form my button getting a black border. By the way i set BorderSize to "0" and it works great while i clicking inside of my form.
this.button.FlatAppearance.BorderSize = 0;
That's how it looks like.
it seems a focus problem. Try to reset the focus when the cursor leave the control.
Add these lines of code to your forms load event.
btn.FlatStyle = FlatStyle.Flat;//You can also use the popup flat style
btn.FlatAppearance.BorderColor = btn.Parent.BackColor;
btn.FlatAppearance.BorderSize = 0;
One simple workaround is to set the FlatAppearance.BorderColor of the Button to its Parent.BackColor:
this.button1.FlatAppearance.BorderColor = this.button1.Parent.BackColor;
You could set this Property subscribing to the ParentChanged event (or overriding OnParentChanged, if it's a Custom Control) if the Control can be assigned to another parent at some point.
You can also perform the same operation in batch, using the HandleCreated event and have all the Buttons (with FlatStyle = FlatStyle.Flat) subscribe to the event in the Form's constructor:
public Form1()
{
InitializeComponent();
foreach (Button button in this.Controls.OfType<Button>().Where(btn => btn.FlatStyle == FlatStyle.Flat))
{
button.HandleCreated += (s, e) => {
button.FlatAppearance.BorderColor = button.Parent.BackColor;
};
}
}
I have a number of buttons on a Windows Form. I only want to disable a number of them.
I have created a list of buttons and added the buttons that i want to disable. When i run the code the buttons are still enabled.
Below is what i have tried.
private List<Button> buttonsToDisable = new List<Button>();
buttonsToDisable.Add(btn1);
buttonsToDisable.Add(btn2);
buttonsToDisable.Add(btn3);
foreach (var control in this.Controls)
{
if (control is Button)
{
Button currentButton = (Button)control;
if (buttonsToDisable.Contains(currentButton))
{
currentButton.Enabled = false;
}
}
}
Can anyone see why this wont disable the button for me.
Any advice is welcome.
Why not simply?:
foreach(Button btn in buttonsToDisable)
{
btn.Enabled = false;
}
currentButton.Enabled = false;
this.Controls.Add(currentButton);
answering your question - your code would work if the buttons were direct descendants of the form - i.e. they were placed straight onto it.
If however you placed them in another container (e.g. a groupbox), then your code would need to change to something like:
foreach (var control in groupBox1.Controls)
If you have multiple levels of complexity, then you'd be looking at a recursive function to get to the buttons within their parents, and their parents, etc.
As others have pointed out, you could always just iterate over buttonsToDisable.
If is directly added to the form, then u just foreach Controls collection and disable buttons.
Button btn1 = new Button();
this.Controls.Add(btn1);
Button btn2 = new Button();
this.Controls.Add(btn1);
Button btn3 = new Button();
this.Controls.Add(btn1);
buttonsToDisable.Add(btn1);
buttonsToDisable.Add(btn2);
buttonsToDisable.Add(btn3);
foreach (var control in this.Controls)
{
((Button)control).Enabled = false;
}
or
foreach (var button in buttonsToDisable)
{
button.Enabled = false;
}
I have a form with a simple calculator with the size 245 x 359.
I currently have a show/hide button for scientific functions.
I want to be able to click a button and have it show the scientific functions.
With the button size 300 x 400.
In your button click event you can do the following:
this.Size = new Size(300,400);
In the designer, just make these buttons, but then drag it's size to how you want it before the specific button is pressed.
Add a event handler for the button you want, then do this:
bool buttonPressed = false;
private void onChangeSizeButton_pressed(EventArgs e, object o)
{
if (buttonPressed)
{
this.Size = new Size(this.Size.Width, DEFAULT HEIGHT HERE);
buttonPressed = false;
}
else
{
this.Size = new Size(this.Size.Width, NEW HEIGHT HERE);
buttonPressed = true;
}
}
In your button click event, set each scentific function to:
btnMC.Visbile = true;
btnMC.Size = new Size(300, 400);
btnMR.Visbile = true;
btnMR.Size = new Size(300, 400);
ect...
That should do the trick. You might want to considered resizing your form when they click the button as well.
In your example, do not need to hide and show button but only need to change text.
Add Fix button on panel or user control and change the text. If require then user Button.Visible = false and true. Share your sample code for work on it.
Okay so I'm trying to attempt to move a button around on a form. I use the following codes to call the button:
i++;
Button button = new Button();
button.Location = new Point(160, 30 * i + 10);
button.Click += new EventHandler(b_Click);
button.Tag = i;
panel1.Controls.Add(button);
I'm able to click each button and get a Messagebox showing their tag but I want to use their tag as a way to move the buttons around with a timer.
Assuming this is WinForms, you can use a Linq query on the Form Controls collection to find a button by its tag.
var found = (from Control c
in this.Controls
where c.Tag == "ButtonTag"
select c).FirstOrDefault() as Button;
if (found != null)
{
// manipulate the button
}
I should note that this will only find top level controls on the form. It would not find buttons that are inside of a container control (like a panel). If your buttons are in a container, just replace "this" with the name of your container.
var found = (from Control c
in panel1.Controls
where c.Tag == "ButtonTag"
select c).FirstOrDefault() as Button;
I should also note that this could be slow on a form with a large number of controls.