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

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 ^_^.

Related

How to assign values for check boxes for a formula calculation which includes a text box in the formula

I am a new programmer learning to code in C# and I have an C# assignment to be finished and for that I need to make some formulas to calculate rent for tours and for that I decided to use text boxes and check boxes in C# but I cant figure out how to make a formula with the combination of check boxes and a text box.
private void button1_Click_1(object sender, EventArgs e)
{
checkBox1.Text = "50000";
checkBox2.Text = "250000";
checkBox3.Text = "2500";
checkBox4.Text = "10000";
checkBox5.Text = "1500";
if (checkBox1.CheckState == CheckState.Checked &&
checkBox2.CheckState == CheckState.Checked)
{
}
}
The type of control has little to do with creating a formula. To create the formula, you need to know all it's possible inputs and how they should be combined to produce the output. This could be done in a method, for example:
private int GetTotalValue(int vehiclePrice, int driverPrice, int rentDuration)
{
// This is where your formula would go
return (vehiclePrice + driverPrice) * rentDuration;
}
The trick then, is to convert the state of the form controls into values that you can plug into the method. One way to do this (not necessarily the best way, but probably easiest to understand when you're starting) is to check the value of each control and set the appropriate value in the Click event for your Submit button.
For the rent duration, we can use the int.TryParse method, which takes in a string and an "out" int parameter, and returns true if the string is a valid integer, or false if it's not. When it exits, if the conversion was successful, the out parameter will contain the int value.
For the other controls, we could use simple if / else if statements to determine which control was checked, and then set our value accordingly. In this example, we're using temporary variables inside the click event to store the value for each parameter to the method. If none of the required controls are checked, we can show a message to the user and wait for them to finish filling out the form.
In this example I used radio buttons (and used the opt prefix, which is a naming convention from a long time ago that I'm not sure still exists - they used to be called option buttons):
private void btnSubmit_Click(object sender, EventArgs e)
{
// Validate that rent textbox contains a number
int rentDuration;
if (!int.TryParse(txtRentDuration.Text, out rentDuration))
{
MessageBox.Show("Please enter a valid number for rent duration");
return;
}
// Determine vehicle price based on which option was selected
int vehiclePrice;
if (optToyotaPrado.Checked) vehiclePrice = 50000;
else if (optRollsRoyce.Checked) vehiclePrice = 250000;
else if (optSuzikiWagonR.Checked) vehiclePrice = 2500;
else if (optToyotaCorolla.Checked) vehiclePrice = 10000;
else
{
MessageBox.Show("Please select a vehicle");
return;
}
// Determine driver price
int driverPrice;
if (optWithDriver.Checked) driverPrice = 1500;
else if (optWithoutDriver.Checked) driverPrice = 0;
else
{
MessageBox.Show("Please select a driver option");
return;
}
// Finally set the text to the return value of our original method,
// passing in the appropriate values based on the user's selections
txtTotalValue.Text = GetTotalValue(vehiclePrice, driverPrice, rentDuration).ToString();
}
As Rufus said, I'd go with RadioButtons, instead of CheckBoxes. Set the Tag property of the RadioButtons to the vaule you want associated with them and then use a function like this to get the value of the checked item. Just pass in the GroupBox to the function and get back the value of the checked RadioButton.
private int GetGroupBoxValue(GroupBox gb)
{
int nReturn = 0;
foreach (Control ctl in gb.Controls)
{
if (ctl.GetType() == typeof(RadioButton))
{
if (((RadioButton)ctl).Checked)
{
nReturn = Convert.ToInt32(ctl.Tag);
break;
}
}
}
return nReturn;
}
Now all you have to do is use the excellent code Rufus provided for checking for an integer in the rentDuration TextBox and you're golden.

How do I dynamically change the font of winforms listbox item?

How do I make bold a variable amount of items in a listbox? I've seen solutions like this one, but it appears to only work if I know exactly which items should be bold before runtime. Here's my specific case:
I have a listbox with a list of strings read from a file. I have a search bar that, when typed in, will automatically move items matching that string to the top of the listbox. Unfortunately, being at the top isn't enough of an indicator of "search result," so I also want to make those items bold. Before runtime, I do know all the items I want to be bold will be at the top of the list, but I have no idea how many items that will be. Additionally, when the user erases the search bar's contents, the list will be reordered to its initial order and the bold items should be made not bold.
How do I go back and forth between bold/not bold for specific listbox items at runtime?
Here is my code for the search and display functionality:
private void txtSearch_TextChanged(object sender, EventArgs e)
{
string searchTerm = txtSearch.Text.Trim();
if(searchTerm.Trim() == "") // If the search box is blank, just repopulate the list box with everything
{
listBoxAllTags.DataSource = fullTagList;
return;
}
searchedTagList = new List<UmfTag>();
foreach(UmfTag tag in fullTagList)
{
if(tag.ToString().ToLower().Contains(searchTerm.ToLower()))
{
searchedTagList.Add(tag);
}
}
// Reorder the list box to put the searched tags on top. To do this, we'll create two lists:
// one with the searched for tags and one without. Then we'll add the two lists together.
List<UmfTag> tempList = new List<UmfTag>(searchedTagList);
tempList.AddRange(fullTagList.Except(searchedTagList));
listBoxAllTags.DataSource = new List<UmfTag>(tempList);
}
I was able to solve my own problem. I indeed used the solution present in this question, but I altered it like so:
private void listBoxAllTags_DrawItem(object sender, DrawItemEventArgs e)
{
e.DrawBackground();
FontStyle fontStyle = FontStyle.Regular;
if(e.Index < searchedTagList.Count)
{
fontStyle = FontStyle.Bold;
}
if(listBoxAllTags.Items.Count > 0) // Without this, I receive errors
{
e.Graphics.DrawString(listBoxAllTags.Items[e.Index].ToString(), new Font("Arial", 8, fontStyle), Brushes.Black, e.Bounds);
}
e.DrawFocusRectangle();
}
The second if statement (checking if the count is greater than 0) is required. Without it, I received "index[-1]" errors because my program first starts with empty listboxes, and the DrawString method couldn't draw the string for the empty listBox.Items[] array.

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.

Implement a c# windows forms Autocomplete textbox with multiple suggested columns

I am attempting to implement a Windows Forms control in C# that resembles a textbox. When the user types 3 or more characters, a search will be performed against a datasource. There will be multiple fields returned (see the class structure below as one possible definition).
public class MyStructure
{
public int Value1 { get; set; }
public string Value2 { get; set; }
public string Value3 {get; set; }
}
My requirements are to display an autocomplete list containing multiple columns (Note: this can be a string that contains padded fields from the list that are concatenated together). When the user either types all characters, hits the down arrow to select an item, or hits the enter key the value in the textbox will take the ValueMember of the list (where the DisplayMember of the list would be the whole data source). Every keystroke that the user enters that is not an up or down arrow or the enter key will perform another search and refresh the list.
I have seen how to implement a textbox with a single column in an auto-suggest, but cannot find a relatively "simple" example of how to do this for multiple columns. Should the control be a textbox or a combobox that is somehow styled to resemble a textbox (if this is possible) or a user control?
Should the event to monitor keystrokes be the TextEntered or the KeyPress event? Can I reset the AutoCompleteStringCollection without having the contents entered affected (I keep losing my input or my place in the input in any attempts)?
Can anyone provide examples of how to do this in framework 4.0 or above or point me to an example?
EDIT 1:
After much searching, I have found that essentially I need to implement a ContextMenuStrip on the TextBox (anything else and other controls below the user control will be overlapped). My problem is that I cannot determine how to handle the Key press events such as Tab and Enter. In addition, I need to handle if the user continues typing (in this event, I want to switch focus back to the textbox and add the key). Below is my code:
private void textBox1_TextChanged(object sender, EventArgs e)
{
ContextMenuStrip menuStrip;
string szMenuItem = string.Empty;
// This would actually be a call to a web service
List<MStarDeal> deals = DealInfo.Where(i => i.Value1.StartsWith(textBox1.Text.ToUpper()) || i.Value2.StartsWith(textBox1.Text.ToUpper()) || i.Value3.StartsWith(textBox1.Text.ToUpper()))
.Select(i => i).ToList();
if (textBox1.Text.Length >= 3 && !bSelected)
{
menuStrip = new System.Windows.Forms.ContextMenuStrip();
foreach (MStarDeal item in deals)
{
szMenuItem = item.Value1.PadRight(15) + item.Value2.PadRight(20) + item.Value3.PadRight(80);
ToolStripItem tsItem = new ToolStripMenuItem();
tsItem.Text = szMenuItem;
tsItem.Name = item.Value1;
tsItem.MouseUp += tsItem_MouseUp;
menuStrip.Items.Add(tsItem);
}
textBox1.ContextMenuStrip = menuStrip;
textBox1.ContextMenuStrip.Show(textBox1, new Point(0, 20));
}
else if (bSelected)
{
bSelected = false;
}
}
void tsItem_MouseUp(object sender, EventArgs e)
{
bSelected = true;
textBox1.Text = ((ToolStripMenuItem)sender).Name;
}
Thanks,
Lee
I think I understand your question. How about using the TextChanged() event instead of KeyPress? As far as the columns, a flowLayoutPanel will render columns if you set it up to flow in the right direction and make its size appropriate to the width of the two columns combined.

c# set ListBox to RTL

As an attempt to color text in ListBox i found this guide C# : change listbox items color (i am using windows forms application on visual studio 2012).
The code is working but the problem is that i want to use the textbox in a Right to Left mode, but when i change it in the ListBox settings it does not work, so i assume that it needs to be changed in the code somehow, this is what i need your help for.
Thank you very much!
Alon
Your y position is 0, so everytime you insert a message it's on the left side.
To put it on the right side you have recalculate the postion.
Look at the following example.
private void listBox1_DrawItem(object sender, DrawItemEventArgs e)
{
MyListBoxItem item = listBox1.Items[e.Index] as MyListBoxItem; // Get the current item and cast it to MyListBoxItem
if (item != null)
{
e.Graphics.DrawString( // Draw the appropriate text in the ListBox
item.Message, // The message linked to the item
listBox1.Font, // Take the font from the listbox
new SolidBrush(item.ItemColor), // Set the color
width - 4, // X pixel coordinate
e.Index * listBox1.ItemHeight,
new StringFormat(StringFormatFlags.DirectionRightToLeft)); // Y pixel coordinate. Multiply the index by the ItemHeight defined in the listbox.
}
else
{
// The item isn't a MyListBoxItem, do something about it
}
}
A list box is natively left-justified and you cannot change this in the UIR editor. You can apply the appropriate justification elements while creating the string to pass to the list box: see the online help for Item Label parameter of the InsertListItem function. All escape codes are to be applied to every line that you insert into the list box; there is no way to apply a default formatting style to the control.

Categories

Resources