Identifying indexes in an array that haven't been used - c#

OK so I have created an array of four buttons, when one of the buttons is clicked the background colour will change and the value of that button will be stored in a variable. however, if another button is clicked then I want the button that was clicked originally to revert back to the background colour it was originally, while the new button will change its background colour. I.e. only one button at a time will be 'selected'. at the minute i have this:
btn[0].BackColor = Color.DimGray;
btn[1].BackColor = Color.DimGray;
btn[2].BackColor = Color.DimGray;
btn[3].BackColor = Color.DimGray;
btn[selectedIndex].BackColor = Color.Lime;
I was wondering if there is a way for me to isolate the Indexes that aren't selected and setting them all back to the same colour without having to repaeat the same line of code multiple times, i only ask because there are 17 more buttons on the interface and it just looks horrible.

You can set them all in a single for loop, like this:
for (var i = 0 ; i != btn.Length ; i++) {
btn[i].BackColor = (i == selectedIndex)
? Color.Lime
: Color.DimGray;
}
The conditional inside the loop compares i, the current index, to selectedIndex, and determines if the button's background is to be set to lime or dim gray.

Related

Is there a faster way of assigning an image to lots of buttons?

I have a Windows Forms Application that I need to assign an image to all 100 buttons, the problem is, that I need to do it randomly every time... Is there a faster way of doing this?
My first idea was to use the basic method of assigning that image to a variable and then assigning the image to the button:
Bitmap P_Farm = new Bitmap(#"IMAGE PATH.jpeg");
this.button1.Image = P_Farm;
But the problem with that is that I will need to do this for all 100 buttons.
this.button1.Image = P_Farm; // "P_Farm is just the path to the image"
this.button2.Image = P_Farm;
this.button3.Image = P_Farm;
this.button4.Image = P_Farm;
I want to keep my code as dry as possible.
The reason I can't just do it through the "Image" option in the "Properties" window is because eventually I will have a random image for every button on every load of the app. So first it will be
this.button1.Image = Z_Farm;
this.button2.Image = C_Farm;
this.button3.Image = P_Farm;
this.button4.Image = P_Farm;
then
this.button1.Image = P_Farm;
this.button2.Image = P_Farm;
this.button3.Image = Z_Farm;
this.button4.Image = Z_Farm;
I was wondering if it was possible to do something like reading every line in a text file but instead of the line changing with each try, the button changes
int i = 0;
while (true) // Something like this loop but changing not the line, but the button
{
this.button[i].image = P_Farm; // this obviously doesn't work
I++;
}
Hopefully this makes sense
Thanks a lot!
You can also loop through all the controls in your form, find the ones that are buttons and change their image that way. Of course you don't want to change them all. What I usually do is set a number to the Tag property:
foreach (Control control in Controls)
{
if (control is Button theButton && (int)theButton.Tag == 5)
{
theButton.Image = P_Farm;
}
}
This will not work if you have panels with buttons that you want to change too. You will have to write a recursive function that involves all the possible containers in your form such as panels.
If you want to change all the buttons in a container like a panel you would only change your foreach line to something like foreach (Control control in panel.Controls).
In the future, when you decide that not all buttons will have the same image, you could set an image based on the tag property like this:
foreach (Control control in Controls)
{
if (control is Button theButton && (int)theButton.Tag >= 5)
{
switch ((int) theButton.Tag)
{
case 100:
theButton.Image = P_Farm;
break;
case 101:
theButton.Image = Z_Farm;
break;
}
}
}
Because we are assuming that all buttons have an int in their tag property, you should add a number to all buttons, including those that should not change like your Cancel and Ok buttons. Something like a zero to exclude them from the image assignement.
I'm sure that there are better ways. I haven't done WinForms in a while.

C# - DropDown ComboBox - how can a user add value using nothing else?

I would like to solve my problem using only a DropDown ComboBox component. Although I have a list of colors, I want to allow user to enter an RGB color code.
In my imagination it would work two ways:
The user opens the Dropdown section and choses the wanted color
The user enters an RGB code (eg. 255;0;123) through the component's editable first line (then presses enter)
(I don't need (neither want) the RGB code to be added to the list of the ComboBox.)
I only need the results of that; I can process the outcoming data.
You need to use the ComboBox's "KeyDown" event. In the below I'm using "exampleProcess" as a method used when you have a colour you wish to use. I'm going to add an array of your example colours as comparisons also.
string[] colours = new string[]{"Red","Green","Blue","Yellow","etc"};//These would be the values in your combobox dropdown list.
Color selectedcolour;
private void ComboBox_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)//If enter key pressed.
{
if (colours.Contains(ComboBox.Text))//If the colour is one of the default colours.
{
selectedcolour = Color.FromName(ComboBox.Text);
}
else
{
List<string> parts = ComboBox.Text.Split(';');//Split text into parts between each ";".
foreach(string part in parts)
{
if (part == "")
{
parts.Remove(part);
}
}
int r = int.Parse(parts[0]);
int g = int.Parse(parts[1]);
int b = int.Parse(parts[2]);
selectedcolour = Color.FromArgb(r,g,b);
}
exampleProcess(selectedcolour);
}
}
You'll have to add more error checking but I think this should essentially work ^_^.

C# - Trying to create a "selected" state for several buttons

What I want to do is creating a menu with several buttons and when the user clicks on one of them, the selected button tag gets stored in a variable and the background color of that button gets highlighted. When the user clicks another button, the previous stored variable gets compared with the new variable and if it is different, it changes the background color of the earlier pressed button back to normal. This is what I have so far:
if (!isSelected)
{
b.BackColor = Color.FromArgb(28, 145, 162);
previousPress = (int)b.Tag;
isSelected = true;
if(previousPress != currentPress)
{
b(previousPress).BackColor = Color.FromArgb(12, 34, 567); // Obviously this wont work, but hopefully it clears up on what I want to reach.
isSelected = false;
currentPress = (int)b.Tag;
}
}
The .Tag idea of B is ranging from 1 till 7, as that is how many buttons are created in the constructor method.
That is what I tried to use, but someone suggested I shouldn't be using tags for this, as it should only cause bugs and errors. He suggested the following:
Button previousButton = b;
if (previousButton != currentButton)
...
I understand the logic behind this, but sadly before he went away before I could ask where and how the currentButton variable is declared/used. Could someone shine some light upon this? Thank you!
Assuming that all the buttons are assigned the same Click event, this code would do exactly what you want:
Color _activeColor = Color.Red;
private void buttons_Click(object sender, EventArgs e)
{
foreach (Button btn in this.Controls.OfType<Button>()
.Where(b => b.BackColor == _activeColor))
{
btn.BackColor = SystemColors.Control;
}
((Button)sender).BackColor = _activeColor;
}
It clears out the button who previously had _activeColor and sets the color to the current one.
This is pretty common approach to what (I believe) you need. Try to understand this code before trying it, it's relying on Linq.

c# wpf button with variable as name? same colours in all buttons

Hello I have 2 questions.
This is my code: (kolLos make random number between 0 and 255)
public int numer_prostokata = 1;
private void Glowny_przycisk_Click(object sender, RoutedEventArgs e)
{
// Create a Button
Button blueRectangle = new Button();
blueRectangle.Content = numer_prostokata;
var nazwa_batona = "s_b_" + numer_prostokata;
blueRectangle.Name = nazwa_batona;
MainWindow.Children.Add(blueRectangle);
myColor.Color = Color.FromArgb(kolLos(), kolLos(), kolLos(), kolLos());
blueRectangle.Background = myColor;
numer_prostokata++;
}
It almost work. Buttons are generating on click. They have different Contents, but... always the same color. Colors are changing after each Click, but all buttons have the same (for example all red or all blue)...
What I did wrong?
And second question:
name of Buttons is "s_b_" + number. It is in var "nazwa_batona". But when I use
nazwa_batona.Background = myColor;
it doesn't work... What should I do?
I'm very begining in C#... I googled and searched many hours but didn't find answers...
Oh! There can be many buttons created and they can be in different places...
I'm assuming myColor is some class level SolidColorBrush since it isn't declared in the function. Given that, the following code simply changes the color of that brush, then assigns the brush to the new button instance:
myColor.Color = Color.FromArgb(kolLos(), kolLos(), kolLos(), kolLos());
blueRectangle.Background = myColor;
However, every button has the same brush instance, so when you change the color for the next button, all the previous ones change as well.
You need to create a new brush:
SolidColorBrush backgorundBrush = new SolidColorBrush();
backgorundBrush.Color = Color.FromArgb(kolLos(), kolLos(), kolLos(), kolLos());
blueRectangle.Background = backgorundBrush;

Changing the color of dynamically created buttons not using clicked at event

I have added buttons to a grid layout I created. Here is the code for that.
int nodeIndex = 0;
for (i = 0; i < usedRows; i++)
{
for (j = 0; j < cols; j++)
{
this.tableLayoutPanel1.Controls.Add(nodes[nodeIndex++], j, i);
}
}
Later on in the application I want to be able to change the color of a button at a specified position. Basically change the back round color of the button at position i,j. How would I get access to that specific button? I am using winforms. Is there something like
button = this.tableLayoutPanel1.Controls.GetChildAtPosition(j, i)
You can use something along these lines.
button = this.tableLayoutPanel1.GetControlFromPosition(j, i);
button.BackColor = Color.BLACK;
So first you want to able to find the control and conveniently there is a method called FindControl() that can do just that
MSDN link for reference: http://msdn.microsoft.com/en-us/library/system.web.ui.control.findcontrol(v=vs.110).aspx
Second you want to be able to change the color of the button once you find it.
For buttons you probably want to use the BackColor property.
Again MSDN link for reference:
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.backcolor(v=vs.110).aspx
The trick is going to be finding the control and then working with that control as an object to change the color. Don't forget that you can cast the control to a button type once you find it, which should give you access to the BackColor property.

Categories

Resources