How to deselect all controls in a form? - c#

I have dynamically created a list of buttons and set it to the form. After clicking one of them, the very next button to it will appear as selected.
Is it possible to deselect all controls dynamically created in a form? Particularly, can I, somehow, deselect that button after clicking the one before it?
private void GenerateButton()
{
for (int i = 1; i <= 15; ++i)
{
for (int j = 1; j <= 25; ++j)
{
Button button = new Button();
button.Location = p;
button.Size = size;
button.BackColor = Color.RoyalBlue;
button.Padding = pad;
button.Click += new EventHandler(button_Click);
this.Controls.Add(button);
p.X += 23;
}
p.Y += 23;
p.X = 0;
}
}
protected void button_Click(object sender, EventArgs e)
{
Button but = sender as Button;
but.Enabled = false;
but.BackColor = Color.LightGray;
}

You might try this method, which will select the next button in the form, after clicking on a button. You need to attach this button event handler to all your buttons. The order of buttons is determined by their order in the form Controls list. If you want a specific order, you will need to use LINQ to sort Controls by their TabOrder property and ensure your TabOrder is set properly
private void button_Click(object sender, EventArgs e)
{
var btn = (Control)sender;
btn.Enabled = false;
btn.BackColor = Color.LightGray;
// Where is this button in the form?
var indexOfThisButton = this.Controls.IndexOf(btn);
// Find next button index
for (int i = indexOfThisButton+1; i < this.Controls.Count; i ++)
{
// If it's a button, select it
if (this.Controls[i] is Button)
{
this.Controls[i].Select();
return;
}
}
// If we got down here we have got to the end of the controls list, start again
for (int i = 0; i < this.Controls.Count; i++)
{
// If it's a button, select it
if (this.Controls[i] is Button)
{
this.Controls[i].Select();
return;
}
}
}

Related

What event is triggered when the mouse pointer enters a MenuflyoutSubItem element?

PointerEntered is triggered when the mouse pointer enters a MenuFlyoutItem, but not when it enters a MenuFlyoutSubItem. What event is triggered when the mouse pointer enters a MenuflyoutSubItem element? I want to capture the text property of the MenuflyoutSubItem element in an event handler when the mouse pointer enters it. (The reason I can't rely on the tapped event is because even just hovering over the MenuFlyoutSubItem opens its contained menu items.) Here is the code:
public DynamicMenuTestPage()
{
InitializeComponent();
for (int i = 0; i < 5; i++)
{
MenuFlyoutSubItem myItem = new MenuFlyoutSubItem();
myItem.Text = "Item" + i;
myItem.PointerEntered += MyItem_PointerEntered;
MyMenu.Items.Add(myItem);
for (int j = 0; j < 4; j++)
{
MenuFlyoutItem mySubItem = new MenuFlyoutItem();
mySubItem.Text = "SubItem" + j;
mySubItem.PointerEntered += mySubItem_PointerEntered;
myItem.Items.Add(mySubItem);
}
}
}
private void MyItem_PointerEntered(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
// This does not work. It is not triggered when the mouse pointer enters the menu flyout subitem.
MenuFlyoutSubItem test = sender as MenuFlyoutSubItem;
var menuFlyoutSubItemText = test.Text;
}
private void mySubItem_PointerEntered(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{ //This works. It is triggered when the mouse pointer enters the menu flyout item.
MenuFlyoutItem test = sender as MenuFlyoutItem;
var menuFlyoutItemText = test.Text;
}
Here is a screenshot of the menu. When I hover over Item0, circled in red, the submenu opens. What event will enable me to capture the text, "Item0"?
It seems the MenuFlyoutSubItem doesn't fire the PointerEntered RoutedEvents, you can wire an event handler for this RoutedEvents.
myItem.AddHandler(PointerEnteredEvent, new PointerEventHandler(PointEnterHandler), true);
So your code will be like this:
public MainPage()
{
this.InitializeComponent();
for (int i = 0; i < 5; i++)
{
MenuFlyoutSubItem myItem = new MenuFlyoutSubItem();
myItem.Text = "Item" + i;
myItem.AddHandler(PointerEnteredEvent, new PointerEventHandler(PointEnterHandler), true);
MyMenu.Items.Add(myItem);
for (int j = 0; j < 4; j++)
{
MenuFlyoutItem mySubItem = new MenuFlyoutItem();
mySubItem.Text = "SubItem" + j;
mySubItem.PointerEntered += mySubItem_PointerEntered;
myItem.Items.Add(mySubItem);
}
}
}
private void PointEnterHandler(object sender, PointerRoutedEventArgs e)
{
MenuFlyoutSubItem test = sender as MenuFlyoutSubItem;
var menuFlyoutSubItemText = test.Text;
}
private void mySubItem_PointerEntered(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{ //This works. It is triggered when the mouse pointer enters the menu flyout item.
MenuFlyoutItem test = sender as MenuFlyoutItem;
var menuFlyoutItemText = test.Text;
}

Change background of a button when clicking another button

I am currently experimenting in WPF and just created a UniformGrid with 800 buttons which are created in a for loop. All buttons have their own names and share the same click event.
What I want to do now is the following: I want to click the first button (rect0) to change the color of this button and the next one (rect1).
I am totally stuck right now because everything I write into the click event refers to the button I clicked.
public MainWindow()
{
InitializeComponent();
for (int i = 0; i < 800; i++)
{
Button BTN_rect = new Button()
{
Name = "rect" + i,
Background = Brushes.White,
};
BTN_rect.Click += BTN_rect_Click;
Uniform.Children.Add(BTN_rect);
}
}
private void BTN_rect_Click(object sender, RoutedEventArgs e)
{
Button BTN_rect = sender as Button;
BTN_rect.Background = Brushes.Red;
MessageBox.Show(BTN_rect.Name);
}
There are a load of ways to do this.
I took a shortcut and put just 9 buttons in a stackpanel, otherwise the same.
public MainWindow()
{
InitializeComponent();
for (int i = 0; i < 8; i++)
{
Button BTN_rect = new Button()
{
Name = "rect" + i,
Content =Name,
Tag = i,
Background = Brushes.White,
};
BTN_rect.Click += BTN_rect_Click;
sp.Children.Add(BTN_rect);
}
}
private void BTN_rect_Click(object sender, RoutedEventArgs e)
{
Button current = sender as Button;
current.Background = Brushes.Red;
string targetName = $"rect{((int)current.Tag) + 1}";
Button nextButton = sp.Children.OfType<Button>().Where(x => x.Name == targetName).SingleOrDefault();
nextButton.Background = Brushes.Red;
}
Usually, you'd template data into repeated controls rather than add them in code, btw.

How to specify interaction beetween button click event handlers?

In the program, by clicking button2, is created a table and imlemented data insertion. Also created textbox and login button, which is used for reading data from this textbox. When the login button is pressed, next actions should happen:
MessageBox should display some text;
login.Text should be changed;
table, which was created by clicking button2 should be deleted.
I dont know actually how to get access from login.click event handler to table in button2. I guess it should be done somehow by using EventArgs, but i dont understand how. Also I thought about creating some variable outside button2 handler scope, and use it later, but I guess its a bad practise.
Please,tell me how to solve this, or maybe its just wrong decision to create windows forms components such a way? if it`s so, then how to?) here is my code:
private void button2_Click(object sender, EventArgs e)
{
label1.Hide();
label2.Hide();
textBox1.Hide();
textBox2.Hide();
button2.Hide();
int user_count = Int32.Parse(textBox2.Text);
int file_count = Int32.Parse(textBox1.Text);
DataGridView T = new DataGridView();
T.Dock = DockStyle.Top;
T.AutoResizeColumns();
T.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
T.ColumnCount = file_count + 1;
T.RowCount = user_count + 1;
Controls.Add(T);
Controller_cs c = new Controller_cs(user_count, file_count);
for(int i = 1; i < T.RowCount; i++)
{
T.Rows[i].Cells[0].Value = c.user_name_insertion(i-1);
}
for (int i = 1; i < T.ColumnCount; i++)
{
T.Rows[0].Cells[i].Value = c.file_name_insertion(i - 1);
}
for(int i = 1; i < T.RowCount;i++)
{
for(int j = 1; j < T.ColumnCount;j++)
{
T.Rows[i].Cells[j].Value = c.rigts_insertion(j-1,i-1);
}
}
Label l = new Label();
l.Text = "Name";
l.Left = 20;
l.Top = 180;
Controls.Add(l);
TextBox username = new TextBox();
username.Left = 20;
username.Top = 210;
Controls.Add(username);
Button login = new Button();
login.Text = "Enter";
login.Left = 130;
login.Top = 175;
login.Click += login_handler;
Controls.Add(login);
}
private void login_handler(object sender, EventArgs e)
{
Button b = (Button)sender;
if (b.Text == "Enter")
{
b.Text = "Exit";
MessageBox.Show("Enter is done");
}
else
{
b.Text = "Enter";
MessageBox.Show("Quit is done");
}
}

Eventhandler for multiple generated buttons C#

I have generated multiple buttons when I click on btnStart and I'd like to use booleans for each button to become true when it gets clicked so I can check the clicked buttons later on but I only know how to use the same event for every button
This is what I use to create the buttons (I left some unnecessary things out)
for (int i = 0; i < 5; i++) //I use this to horizontally generate buttons
{
for (int j = 0; j < 4; j++) //vertically generate buttons
{
Button btnNew = new Button();
btnNew.Name = "btnFlag" + i;
btnNew.Click += new EventHandler(btnNew_Click);
Controls.Add(btnNew);
aButtons.Add(btnNew); //this is a list I use to set random bgImages
}
}
Now when I click on btnNew it would do all the code set for the event btnNew_Click but I can't use btnFlag1_Click because it doesn't exist, does anyone know a way to create booleans for every buttons and set one to true when a specific button is being clicked
Like: when btnFlag1 gets clicked, turn boolean btn1 to true
and so on ..
Thank you in advance
When you are looping in your for statement you are assigning same event to all your methods.But the sender paramater of your method contains the reference of the button which is calling the specific event.
you can bind all the buttons to same event
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 4; j++)
{
Button btnNew = new Button();
btnNew.Name = "btnFlag" + i;
btnNew.Click += new EventHandler(btnNew_Click);
}
}
Then inside the button click new event you can select your specific sender and perform specific actions
public void btnNew_Click(object sender, ButtonEventArgs e)
{
Button b = sender as Button;
if( b.Name == "btnFlag0" )
{
//logic for your 1st btn
}
//.... repeat the same logic for others
}
You can use the sender argument in the event handler, which in fact is the specific Button which was clicked:
private void btnNew_Click(Object sender, EventArgs e)
{
Button btn = sender as Button;
string name = btn.Name;
}

How to make submit button appear after all text boxes are full?

I'm making a game with 6 dynamic buttons as "btn" at the top row and other 6 "lamp buttons" on a buttom row.
Player clicks on a top row button and text displayed in a bottom row button after clicking on it.
As soon as all the lamp buttons are full with text, I want a submit buttom to appear.
I tried to make for and foreach for my lamp buttons and it didn't help. Plese help!
here is a code:
public partial class Game : System.Web.UI.Page
{
protected void Page_Init(object sender, EventArgs e)
{
for (int i = 0; i < 6; i++)
{
Button btnLamp = new Button();
btnLamp.ID = "btnLamp" + i.ToString();
btnLamp.Click += btnLamp_Click;
this.Panel1.Controls.Add(btnLamp);
}
LiteralControl ltBreak = new LiteralControl();
ltBreak.Text = "<br/><br/>";
Panel1.Controls.Add(ltBreak);
Panel1.DataBind();
for (int i = 0; i < 6; i++)
{
Button btn = new Button();
btn.ID = "btn" + i.ToString();
btn.Text = "btn" + i.ToString();
btn.Click += btn_Click;
this.Panel2.Controls.Add(btn);
}
Panel2.DataBind();
}
void btn_Click(object sender, EventArgs e)
{
Button clickedbutton = (Button)sender;
string btn_cliked = clickedbutton.ID;
for (int i = 0; i <5 ; i++)
{
((Button)FindControl(("btn" + i.ToString()))).BackColor = System.Drawing.Color.LightSteelBlue;
}
clickedbutton.BackColor = System.Drawing.Color.Beige;
Session["clickedbutton"] = clickedbutton;
}
void btnLamp_Click(object sender, EventArgs e)
{
Button clickedbutton = (Button)sender;
string btnLamp_cliked = clickedbutton.ID;
((Button)FindControl(((Button)Session["clickedbutton"]).ID)).Enabled = false;
for (int i = 0; i < 5; i++)
{
if (((Button)Session["clickedbutton"]).Text.ToString() == ((Button)FindControl("btnLamp" + i)).Text)
{
((Button)FindControl("btnLamp" + i)).Text = "";
}
}
clickedbutton.Text = ((Button)Session["clickedbutton"]).Text.ToString();
}
This sort of stuff is best handled client side in javascript.
Attach a handler to the onchange event of your inputs and figure out inside it if
all inputs have value. Then show your button on page (should be present but hidden - display:none).
If none of the above makes any sense i suggest to do some research on web programming. Figure out the purpose of server code (C# in your case) versus html and javascript. Then come back with questions if needed

Categories

Resources