I have a method that appends or inserts characters to the text of either a combo box or textbox depending on what was last focused on. I am using buttons to pass in the character as a parameter, Using a keyboard or sendkeys is not an option. When my method appends or inserts characters into a textbox the result is as expected however when the same method is applied to a combobox the text of the combobox is highlighted. Obviously this is not the functionality im looking for and I believe this is stopping the autocomplete mode from working correctly.
Why is the combobox behaving differently than the textbox?
The code:
private void createText(string lowerCaseChar, string upperCaseChar)
{
Control FocusedTextComboBox;
switch (lastTextComboBoxFocused)
{
case 54:
FocusedTextComboBox = SearchTextBox;
break;
case 4:
FocusedTextComboBox = VendorComboBox;
break;
case 6:
FocusedTextComboBox = SectionComboBox;
break;
case 5:
FocusedTextComboBox = DeptComboBox;
break;
default:
FocusedTextComboBox = SearchTextBox;
break;
}
if (FocusedTextComboBox is TextBox)
{
TextBox FocusedTextBox = (TextBox)FocusedTextComboBox;
int SelectionStartNumber = FocusedTextBox.SelectionStart;
switch (shift)
{
case true:
FocusedTextBox.Text = FocusedTextBox.Text.Insert(FocusedTextBox.SelectionStart, upperCaseChar);
break;
case false:
FocusedTextComboBox.Text = FocusedTextComboBox.Text.Insert(FocusedTextBox.SelectionStart, lowerCaseChar);
break;
}
FocusedTextBox.SelectionStart = SelectionStartNumber + 1;
FocusedTextBox.Focus();
}
else
{
ComboBox FocusedComboBox = (ComboBox)FocusedTextComboBox;
if (FocusedComboBox.SelectionStart == 0 && FocusedComboBox.Text != "")
{
switch (shift)
{
case true:
FocusedComboBox.Text += upperCaseChar;
break;
case false:
FocusedComboBox.Text += lowerCaseChar;
break;
}
}
else
{
int SelectionStartNumber = FocusedComboBox.SelectionStart;
switch (shift)
{
case true:
FocusedComboBox.Text = FocusedComboBox.Text.Insert(FocusedComboBox.SelectionStart, upperCaseChar);
break;
case false:
FocusedTextComboBox.Text = FocusedTextComboBox.Text.Insert(FocusedComboBox.SelectionStart, lowerCaseChar);
break;
}
FocusedComboBox.SelectionStart = SelectionStartNumber + 1;
}
FocusedComboBox.Focus();
}
}
I think setting focus back to the combobox is highlighting the text, move FousedCombox.Focus() to before assigning text to combobox.
Related
I'm trying to make a hangman game in C#. I've done most of the work. I use dynamic buttons as keyboard. My problem is, that when user clicks on a letter on keyboard that is not present in the word that user should estimate, picturebox should replaced with picturebox2, and if his estimation is again wrong, replace with picturebox3, go on until final picturebox. However, if user estimates the letter correctly, picturebox should not replaced. I tried to do this, but my code does not work, as when I click on a button, picturebox keep changing until the last picture even if my estimation is correct or not. where is my mistake?
Here is the part of my code:
void btn_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
btn.BackColor = Color.Aqua;
btn.ForeColor = Color.Red;
int a = 0;
// xy is the word that user should estimate
for (int i = 0; i < xy.Length; i++)
{
if (this.Controls.Find("txt" + i, true)[0].Text == btn.Text)
{
this.Controls.Find("txt" + i, true)[0].Text = btn.Text;
this.Controls.Find("txt" + i, true)[0].BackColor = Color.White;
}
else
{
a++;
switch(a)
{
case 1:
pictbx.Image = Image.FromFile("D:/Csharp_Pro/Games/Mine/hangman/hangman/skeleton1.png");
break;
case 2:
pictbx.Image = Image.FromFile("D:/Csharp_Pro/Games/Mine/hangman/hangman/skeleton2.png");
break;
case 3:
pictbx.Image = Image.FromFile("D:/Csharp_Pro/Games/Mine/hangman/hangman/skeleton3.png");
break;
case 4:
pictbx.Image = Image.FromFile("D:/Csharp_Pro/Games/Mine/hangman/hangman/skeleton4.png");
break;
case 5:
pictbx.Image = Image.FromFile("D:/Csharp_Pro/Games/Mine/hangman/hangman/skeleton5.png");
break;
default:
break;
}
}
}
}
First mistake is what Hans mentioned in comments: your variable must be a field of the class and not a local variable on the function, and must reset on each new game.
Second mistake: you check the letter the player clicked against every letter on the word, and for everytime it doesn't match, you add one to your error counter. You must add 1 only after you have finished checking all the letters in your word.
void btn_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
btn.BackColor = Color.Aqua;
btn.ForeColor = Color.Red;
bool found = false;
// xy is the word that user should estimate
for (int i = 0; i < xy.Length; i++)
{
if (this.Controls.Find("txt" + i, true)[0].Text == btn.Text)
{
this.Controls.Find("txt" + i, true)[0].Text = btn.Text;
this.Controls.Find("txt" + i, true)[0].BackColor = Color.White;
found = true;
}
}
if (!found)
{
a++;
switch(a)
{
case 1:
pictbx.Image = Image.FromFile("D:/Csharp_Pro/Games/Mine/hangman/hangman/skeleton1.png");
break;
case 2:
pictbx.Image = Image.FromFile("D:/Csharp_Pro/Games/Mine/hangman/hangman/skeleton2.png");
break;
case 3:
pictbx.Image = Image.FromFile("D:/Csharp_Pro/Games/Mine/hangman/hangman/skeleton3.png");
break;
case 4:
pictbx.Image = Image.FromFile("D:/Csharp_Pro/Games/Mine/hangman/hangman/skeleton4.png");
break;
case 5:
pictbx.Image = Image.FromFile("D:/Csharp_Pro/Games/Mine/hangman/hangman/skeleton5.png");
break;
default:
break;
}
}
}
It still has a lot of room for improvement, buy I decided to stop here so you can eventually find it out by yourself while you're learning.
I am trying to make a minesweeper game using Windows Application. I would like to use a switch inside a method.
The problem:
public void switcher()
{
switch (x)
{
case 0:
A1.BackgroundImage = Image.FromFile("empty.jpg"); // look at A1
break;
case 1:
A1.BackgroundImage = Image.FromFile("1.jpg");
break;
case 2:
A1.BackgroundImage = Image.FromFile("2.jpg");
break;
case 3:
A1.BackgroundImage = Image.FromFile("3.jpg");
break;
case 4:
A1.BackgroundImage = Image.FromFile("4.jpg");
break;
case 5:
A1.BackgroundImage = Image.FromFile("5.jpg");
break;
case 6:
A1.BackgroundImage = Image.FromFile("6.jpg");
break;
case 7:
A1.BackgroundImage = Image.FromFile("7.jpg");
break;
case 8:
A1.BackgroundImage = Image.FromFile("8.jpg");
break;
}
}
As you can see, each of them says "A1. ....." A1 is my first button's name, but there are many other buttons as well. Is there a way I can refer to the button's properties, such as background image, without having to use its name? It would make programming so much easier.
Here's a simplified part of the button, if it helps:
private void A1_Click(object sender, EventArgs e) // < - I want to refer to this without using A1 name.
{
x = bombcount[0, 0];
switcher();
}
edit: One of the answers worked. I don't know much about these things, but I'll try to learn more about them! Thank you!
You need to refactor this code altogether. Don't rely on private members such as x like that, use method parameters:
private void SetButtonImage(Button button, int number)
{
string imagePath;
if (number == 0)
{
imagePath = "empty.jpg";
}
else
{
imagePath = number + ".jpg";
}
button.BackgroundImage = Image.FromFile(imagePath);
}
Then call it like this:
private void Button_Click(object sender, EventArgs e)
{
var button = sender as Button;
int number = bombcount[0, 0];
SetButtonImage(button, number);
}
Now you can hook up all button click events to that single event handler, and you can remove the x member, and you can remove the switch altogether.
Get a reference in switcher to the button being clicked like this:
private void A1_Click(object sender, EventArgs e)
{
Button myB = (Button) sender;
x = bombcount[0,0];
switcher(myB);
}
private void switcher(Button button)
{
switch (x)
{
case 0:
button.BackgroundImage = Image.FromFile("empty.jpg"); // look at A1
break;
case 1:
button.BackgroundImage = Image.FromFile("1.jpg");
break;
case 2:
button.BackgroundImage = Image.FromFile("2.jpg");
break;
case 3:
button.BackgroundImage = Image.FromFile("3.jpg");
break;
case 4:
button.BackgroundImage = Image.FromFile("4.jpg");
break;
case 5:
button.BackgroundImage = Image.FromFile("5.jpg");
break;
case 6:
button.BackgroundImage = Image.FromFile("6.jpg");
break;
case 7:
button.BackgroundImage = Image.FromFile("7.jpg");
break;
case 8:
button.BackgroundImage = Image.FromFile("8.jpg");
break;
}
}
I am trying to use the selectedItem command to see what has been selected in the list box and then use the switch to set the activityLevel variable depending on what has been selected. I then need to be able to multiply that variable by the BMR variable that is set as a double. Then the result is displayed in a label.
string activityLevel = lstActivityLevel.SelectedItem.ToString();
switch (activityLevel)
{
case 1:
activityLevel = Convert.ToInt32(ACTIVTY_LEVEL2);
break;
case 2:
activityLevel = Convert.ToInt32(ACTIVTY_LEVEL3);
break;
case 3:
activityLevel = Convert.ToInt32(ACTIVTY_LEVEL4);
break;
case 4:
activityLevel = Convert.ToInt32(ACTIVTY_LEVEL5);
break;
}
//Display BMR in label
lblBMRResult.Text = (BMR*activityLevel).ToString();
You can use SelectedIndex, then each item of lstActivityLevel set to number from 0 to 4:
double activityLevel = 0;
switch (lstActivityLevel.SelectedIndex)
{
case 0:
activityLevel = ACTIVTY_LEVEL1;
break;
case 1:
activityLevel = ACTIVTY_LEVEL2;
break;
case 2:
activityLevel = ACTIVTY_LEVEL3;
break;
case 3:
activityLevel = ACTIVTY_LEVEL4;
break;
case 4:
activityLevel = ACTIVTY_LEVEL5;
break;
}
lblBMRResult.Text = (BMR * activityLevel).ToString();
You convert SelectedItem value to string. And value 1 (int) is not the same as "1" (string)... So, you have to change your switch statement to:
switch (activityLevel)
{
case "1":
blah, blah...
break;
}
and so on..
Or do not call ToString() on SelectedItem.
Or you can use SelectedIndex instead of SelectedItem..
Several places in my program, the RadioButton matching the selected item has to be checked, and I have a lot of if statements like so:
DataRowView TempRow = (DataRowView)ScheduleDataGrid.SelectedItem;
if (Convert.ToString(TempRow["Bio"]) == "Bio1")
{
BioRB1.IsChecked = true;
}
if (Convert.ToString(TempRow["Bio"]) == "Bio2")
{
BioRB2.IsChecked = true;
}
if (Convert.ToString(TempRow["Bio"]) == "Bio3")
and so on... I want to replace all this with something short and smart.
I tried using the number of the bio to relate to the button like so:
string bioselected = Convert.ToString(TempRow["Bio"]);
int i = Convert.ToInt16(bioselected.Substring(bioselected.Length - 1, 1));
BioRB[i].IsChecked = true;
but doing a BioRB[i] doesn't work, it ignores the [i] and says BioRB does not exist. Any other suggestions?
BioRB[i] is not doing anything like what you think it's doing. All variable references (controls included) have to be well-defined at compile time - you can't refer to a control's name by building a string that matches the name.**
Try creating a list of your radio buttons. Then you can index into the list:
List<RadioButton> radioButtons = new List<RadioButton>()
{
BioRB1,
BioRB2
};
string bioselected = Convert.ToString(TempRow["Bio"]);
int i = Convert.ToInt16(bioselected.Substring(bioselected.Length - 1, 1));
radioButtons[i].IsChecked = true;
** Technically you can do this via reflection, but it's far more complex than what you've tried.
Maybe this will look better:
string caseSwitch = Convert.ToString(TempRow["Bio"]);
switch (caseSwitch)
{
case "Bio1":
BioRB1.IsChecked = true;
break;
case "Bio2":
BioRB2.IsChecked = true;
break;
case "Bio3":
BioRB3.IsChecked = true;
break;
default:
Console.WriteLine("Default case...is optional");
break;
}
Also, try doing what Alybaba726 said and use CellContentClick or something like this:
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
DataGridView dgv = (DataGridView)sender;
if(e.ColumnIndex == dgv.Columns["Bio"].Index)
{
string bioSelected = dgv.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString();
switch (bioSelected)
{
case "Bio1":
BioRB1.IsChecked = true;
break;
case "Bio2":
BioRB2.IsChecked = true;
break;
case "Bio3":
BioRB3.IsChecked = true;
break;
default:
Console.WriteLine("Default case...this is optional");
break;
}
}
}
I have made 4 radio buttons and set their tag to wood, diamond, clay, and brick. I want to find the checked one and set a Bitmap property based on the selected radio button. Disregard the fact that it should be split into more methods, that will be done when i refactor. The properties cellBgImage in Map and Cell are null.
void setCellBgImage()
{
string cellBgImage = "";
foreach (Control c in myMap.myForm.Controls)
{
if (c is RadioButton)
{
RadioButton radio = c as RadioButton;
if (radio.Checked)
{
cellBgImage = radio.Tag.ToString();
}
}
}
switch (cellBgImage)
{
case "wood":
myMap.cellBgImage = (Bitmap)Bitmap.FromFile("Images/wood.png");
break;
case "diamond":
myMap.cellBgImage = (Bitmap)Bitmap.FromFile("Images/diamond.png");
break;
case "clay":
myMap.cellBgImage = (Bitmap)Bitmap.FromFile("Images/clay.png");
break;
case "brick":
myMap.cellBgImage = (Bitmap)Bitmap.FromFile("Images/brick.png");
break;
}
foreach (Cell cell in myMap.myCells)
{
cell.myBgImage = myMap.cellBgImage;
}
}
Add a default case to the switch so when none of them are checked you still get a value in myMap.cellBgImage.
default:
myMap.cellBgImage = (Bitmap)Bitmap.FromFile("Images/brick.png");
break;
As you write at the comments your RB are in panel1. so you should do the Foreach like this:
foreach (Control c in this.panel1.Controls)