I have an array with country names in a listBox. When I enter the textBox, I want any country that starts with what's in the textBox to display.
So if I enter : B => Brazil
Not like this: A => Argentina, England
Only if it starts with what's in the textBox. Full words would also work.
The arraylist contains more than just names, but the code below extracts just the names. List2 is the arraylist I want to use for the search.
private void textBox7_TextChanged(object sender, EventArgs e)
{
listBox1.ClearSelected();
listBox1.DataSource = null;
foreach (Country name2 in Mytree.List)
{
List2.Add(name2.name);
Console.WriteLine(List2);
}
}
If your objective is to avoid typing the full country name then there is no need to reinvent a new kind of user interface. The TextBox has already all the plumbing available to do what you are trying to reproduce with your code. All you need is a source of your data and the settings a pair of properties
// Create the list to use as the custom source.
var source = new AutoCompleteStringCollection();
source.AddRange(new string[]
{
"Argentina",
"England",
"Brazil",
"Italy",
"..."
});
textBox1.AutoCompleteCustomSource = source;
textBox1.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
textBox1.AutoCompleteSource = AutoCompleteSource.CustomSource;
Not quite sure but you will want to look at setting the datasource of the listbox to something like
listBox1.DataSource = Mytree.List.Where(a=>a.name.StartsWith(textBox7.Text)
Your example of using a foreach loop to add each item is a little redundant.
private void textBox7_TextChanged(object sender, EventArgs e)
{
listBox1.ClearSelected();
listBox1.DataSource = null;
var matchingCountries = Mytree.List.Where(l=>l.name.StartsWith(textBox7.Text));
foreach (Country name2 in matchingCountries)
{
listBox1.Items.Add(name2.name);
}
}
Related
I'm trying to allow a user to enter ten alphanumeric values into 10 textboxes in ascending order. Once the values are entered I want to use any sorting algorithm to check if the values have been sorted correctly so I can display a message to the user that their ordering was either correct or incorrect. I'm not sure how I can implement this.
the code below is my list of strings that display in random to the user
private void button1_Click(object sender, EventArgs e)
{
listBox1.Items.Clear();
var list = new List<string> { "12fe", "46ge", "7uf", "15gs", "64ku", "42nt", "04bv", "07nh", "03lf", "86nj" };
var random = new Random();
for (var i = 0; i < 10; i++)
{
int index = random.Next(list.Count);
listBox1.Items.Add(list[index]);
}
private void button2_Click(object sender, EventArgs e)
{
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
here is my Listbox that generates random strings and my textboxes for the user to enter them in ascending order
You can use OrderBy by to sort the list item and use SequenceEqual to compare two list order.
private void button2_Click(object sender, EventArgs e)
{
var list = new List<string> { "12fe", "46ge", "7uf", "15gs", "64ku", "42nt", "04bv", "07nh", "03lf", "86nj"};
var orderedList = list.OrderBy(i => i);
MessageBox.Show(orderedList.SequenceEqual(list).ToString());
}
Why do not use .Sort() ?
var list = new List<string> { "12fe", "46ge", "7uf", "15gs", "64ku", "42nt", "04bv", "07nh", "03lf", "86nj" };
list.Sort();
and after place your listBox1
It is possible to add a special button to check the order; This is what I did and this is the result where the order is compared and shown in the MessageBox as you indicated in your question with icons added for greater clarity by the MessageBox rating
I did a program to make sure and this is the picture:
The result of program to check ascending order
And this is the code I used to read the contents of list box and then compare from the list to check if it is ascending order
private void sort_Click(object sender, EventArgs e)
{
List<string> list = new List<string> { };
foreach (string temp in listBox1.Items)
{
list.Add(temp);
}
var ascending_order = list.OrderBy(item => item);
if (ascending_order.SequenceEqual(list))
{
MessageBox.Show("The ordering of the list is correct", "Sort result",MessageBoxButtons.OK,MessageBoxIcon.Information);
}
else
{
MessageBox.Show("The ordering of the list is Incorrect", "Sort result", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
This is my first answer on this site (stackoverflow)!
In your sort button click, take all the 10 texts and put them in an array
var a = new [] {
textbox1.Text,
textbox2.Text,
textbox3.Text,
...
textbox10.Text
};
Now you can sort them using some common LINQ sorting:
var sorted = a.ToList().Sort();
Now you can cehck if they're in the same order with sequenceequal:
var isSame = sorted.SequenceEquals(a);
If this is an academic exercise and you're not expected to use things like LINQ, i suggest you look at making your own sort (bubblesort is an easy algo to write) and your own version of sequenceEqual (use a for loop to step through the two lists checking if the elements are the same)
Bear in mind that by default in C# sorting is case sensitive
I want to display my List<string> in a datatable, from another form. The data from the List<string> is from textbox and combobox. However, the data from textbox is never repeated but the combobox might be similar with previous data displayed. And if this happened, the data displayed in datatable will be “repeated” (I’m unsure on how to describe it). Here is the actual outcome. I would like to see my displayed data to be like this. Below is my code:
Transavestate - class that hold my List
public static List<string> transnumber_list = new List<string>();
public static List<string> combos_list = new List<string>();
Form1 - form that user input values of textbox and combobox
private void button1_Click(object sender, EventArgs e)
{
//Save values in the List
Transavestate.transnumber_list.Add(Textbox1.Text)
Transavestate.combos_list.Add(comboBox2.SelectedItem.ToString());
//Go to Form 2
this.Hide();
Form2 f2 = new Form2 ();
f2.Show();
}
Form2 - form to display values of textbox and combobox
private DataSet ds;
private DataTable dt;
//Method to insert data into dtg1
private void CreateDataSet()
{
ds = new DataSet();
dt = new DataTable("Vehicle Number");
dt.Columns.Add("Column 1", typeof(string));
dt.Columns.Add("Column 2", typeof(string));
foreach (var item in Transavestate.transnumber_list)
{
foreach (var items in Transavestate.combos_list)
{
dt.Rows.Add(item, items);
}
}
ds.Tables.Add(dt);
this.dataGridView1.DataSource = dt;
dataGridView1.AllowUserToAddRows = false;
}
//To run the method
private void dataGridView1_VisibleChanged(object sender, EventArgs e)
{
CreateDataSet();
}
//Go back to Form1
private void button2_Click(object sender, EventArgs e)
{
this.Hide();
Form1 f1 = new Form1();
f1.Show();
}
It seems to me that you have two sequences of strings: a sequence of transNumbers and a sequence of comboItems (in fact they are your transnumber_list and your combos_list, but I don't want to limit myself to the fact that they are Lists, and the names are inconsistent (the first is non-plural, the 2nd is plural?)
Anyway, you say that your sequence of transNumbers contains only unique items, but that your comboItems might contain duplicates (based on some string equality comparer)
Something like this:
IEnumerable<string> transNumbers = new string[] {"1", "2"};
IEnumerable<string> comboItems = new string[] {"A", "A", "A", "B", "A", "B"};
As a result you want something like:
TransNumber ComboItem
"1" "A"
"1" "B"
"2" "A"
"2" "B"
So you want to combine every TransNumber, with every unique comboItem.The order seems not to be important.
With LINQ This is fairly easy. We'll use Enumerable.SelectMany to combine the two sequences and we'll use Enumerable.Distinct to get rid of your duplicates
// SelectMany:
// parameter source: transNumbers
// parameter collectionSelector: comboItems without Duplicates
var transNumberCombiItemCombinations = transNumbers.SelectMany(
// collectionSelector: comboItems without duplicates
combiItems.Distinct(),
// ResultSelector, take a transNumber from the source,
// and a comboItem from collectionSelector to make a new object
(transNumber, comboItem => new
{
Column1 = transNumber,
Column2 = comboItem,
});
If you remove all comments, you'll see that it is really a small piece of code.
Distinct will remove the duplicates. If you consider "myname" and "MYNAME" to be equal, you'll need to provide an IEqualityComparer<string>, for instance StringComparer.OrdinalIgnoreCase.
SelectMany" will do your foreach inside foreach.
The resultSelector will take one transNumber and one comboItem as input to create the output you want. In this case, one object that has two properties: Column1 and Column2.
The result is an IEnumerable. All you have to do is enumerate it into a list or something and add the result to your rows collection:
dt.Rows.AddRange(transNumberCombiItemCombinations.ToList());
I have a drop down list populated in code and the list displays everything as it should BUT if Pink Water Buffalo is selected from the drop down, the text displayed is Yellow Snake Did I set something up incorrectly? This is full syntax (and I have no selected index changed event for the drop down list that could cause err)
protected void Page_Load(object sender, EventArgs e)
{
IP = HttpContext.Current.Request.Params["HTTP_CLIENT_IP"] ?? HttpContext.Current.Request.UserHostAddress;
if (!IsPostBack)
{
message.Visible = false;
populateDDL();
}
}
protected void populateDDL()
{
var item = new List<ListItem>
{
new ListItem("", ""),
new ListItem("Yellow Snake", "9"),,
new ListItem("This item works", "12"),
new ListItem("Pink Water Buffalo", "9"),
};
this.dropdownlistone.DataTextField = "Text";
this.dropdownlistone.DataValueField = "Value";
this.dropdownlistone.DataSource = item;
this.dropdownlistone.DataBind();
}
EDIT
This is my asp that is used to create the drop down list
<asp:DropDownList ID="dropdownlistone" runat="server" Height="20px" Width="278px"
AutoPostBack="true"> </asp:DropDownList>
EDIT #2
It's ugly and a lot of syntax if you have multiple drop down lists, but for me it wasn't a big deal. What I did was added a .0, .1 etc and incremented up for each item in the drop down list. Then used the .Split method to strip out only the relevant piece like so:
protected void populateDDL()
{
var item = new List<ListItem>
{
new ListItem("", ""),
new ListItem("Yellow Snake", "9.0"),,
new ListItem("This item works", "12.1"),
new ListItem("Pink Water Buffalo", "9.2"),
};
this.dropdownlistone.DataTextField = "Text";
this.dropdownlistone.DataValueField = "Value";
this.dropdownlistone.DataSource = item;
this.dropdownlistone.DataBind();
}
String[] stringsplit = dropdownlistone.SelectedValue.ToString().Split('.');
String itemprice = stringsplit[0].Trim();
In your example, the value for "yellow Snake" and "Pink Water Buffalo" are both set to 9. "Yellow Snake" comes first in the list, so that is the one you are getting.
You'll have to figure out a way to make the value unique for each item. Otherwise you will get unexpected results, possibly across different browsers. A method I've used is combining the text and value with a pipe (|):
var item = new List<ListItem>
{
new ListItem("", ""),
new ListItem("Yellow Snake", "9|Yellow Snake"),
new ListItem("This item works", "12|This item works"),
new ListItem("Pink Water Buffalo", "9|Pink Water Buffalo"),
};
Then you can easily get the value by splitting it:
string value = dropdownlistone.SelectedValue.Split('|')[0];
I prefer the pipe as it's hardly ever used as a display value. Using a dot you might run into some issues if the text contains a dot, such as "Yellow Snakes are great, but green ones are the the best."
I have a ComboBox with the following code:
private void comboBox1_TextChanged(object sender, EventArgs e)
{
using (var service = WebServiceHelper.GetCoreService())
{
string physicianXml = service.SearchPhysicians(SessionInfo.Current.ClientCode, SessionInfo.Current.MachineName,
SessionInfo.Current.Username, comboBox1.Text);
var physicians = PhysicianItemList.FromXml(physicianXml);
AutoCompleteStringCollection autoCompleteStringCollection = new AutoCompleteStringCollection();
foreach (var physician in physicians.Items)
{
autoCompleteStringCollection.Add(physician.LastName + ", " + physician.FirstName);
}
comboBox1.AutoCompleteCustomSource = autoCompleteStringCollection;
comboBox1.Select(comboBox1.Text.Length, 0);
}
}
Basically, a user types the first few characters of a physician's name and it should populate the auto-complete list with the top 100 matching records. It works great, but I need to associate it back to a key (either the PK from the table, or the Physician's NPI number). It seems the AutoCompleteStringCollection doesn't support keys. Can anyone suggest a way of doing this? There are approximately 7 million records in the table, so I don't want to prepopulate the ComboBox.
Thanks
When you build your AutoCompleteStringCollection, build a Dictionary<String, int> for the name, id pairs as well. Then use some event (textbox validation or user submit/save click) to lookup and set the id. You could store the dictionary on the textbox Tag.
Edit
For some reason I thought you were working with a textbox control. Forget about the AutoCompleteStringCollection and just build a Dictionary<String, int>. For the combobox set your autocompletesource to ListItems, set the combobox display name and value and set the datasource to the dictionary.
combobox.DisplayMember = "key";
combobox.ValueMember = "value";
combobox.AutocompleteSource = AutocompleteSource.ListItems;
combobox.DataSource = myDictionary;
However you should only populate the datasource and autocomplete once when the user enters n characters in the combobox, otherwise it gets buggy. I tried to use this for a dynamic autocomplete once (eg the list clears if the user clear the text and retypes), but I had to forget about the combobox and use a hybrid textbox listbox approach much like this user
It looks like your problem is that AutoCompleteStringComplete was made specifically for strings (hence, the name).
You may want to look into the parents (IList, ICollection, IEnumerable) and see if you can homebrew something templated toward a key/value struct.
Too late but maybe someone will use this code :
this.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.ListItems;
this.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.SuggestAppend;
RNProveedor rnProveedor = new RNProveedor();
var listaProveedores = rnProveedor.Buscar();
Dictionary<int, String> dicTemp = new Dictionary<int, string>();
foreach (var entidad in listaProveedores)
{
dicTemp.Add(entidad.ProvNro, entidad.ProNombre);
}
this.DataSource = new BindingSource(dicTemp, null);
this.DisplayMember = "Value";
this.ValueMember = "Key";
And to select the value
public int GetValorDecimal()
{
KeyValuePair<int, string> objeto = (KeyValuePair<int, string>)this.SelectedItem;
return objeto.Key;
}
With this example you won't have any problem with duplicated strings as the examples above
This is my code for adding to my list:
List<string> myList = new List<string>();
private void button1_Click(object sender, EventArgs e)
{
ListViewItem myList = new ListViewItem(txtBox1.Text);
myList.SubItems.Add(txtBox2.Text);
myList.SubItems.Add(txtBox3.Text);
myList.SubItems.Add(txtBox4.Text);
listView1.Items.Add(myList);
txtBox1.Text = "";
txtBox2.Text = "";
txtBox3.Text = "";
txtBox4.Text = "";
}
This adds to my list and clears and lets me add another post to my list. The problem is I want to be able to repopulate the textboxes to allow me to update a post in the list.
To make my point more clear, my list looks like this:
Code | Name | Price | In stock
------------------------------
123 aa 122 2
124 bb 111 5
Say I want the first post, can I somehow set all the data back into the textboxes by that identifier or do I have search by index? I would like to be able to put the code in the first textbox then hit a button called retrieve that populates the other textfield kinda like going by the unique key in an sql table but I cant find any info on wether its possible or not.
Why don't you create a class that has Code, Name, Price, In stock, and use a List
Public MyItem
{
public string Code;
public string Name,
public float Price;
public bool inStock;
}
List<MyItem> myList = new List<MyItem>();
private void button1_Click(object sender, EventArgs e)
{
MyItem temp = new MyItem()
temp.Code=txtBox1.Text;
temp.Name=(txtBox2.Text);
temp.Price=(txtBox3.Text);
temp.inStock=(txtBox4.Text);
mylist.add(temp);
txtBox1.Text = "";
txtBox2.Text = "";
txtBox3.Text = "";
txtBox4.Text = "";
}
If you implement it this way then you can just use the index to go through all the items in the list. With the example above you would probably need to convert some of the values from the text boxes before you can use them (price to double)
Also if you want to add the items to a Listview and display them a certain way then override the toString property in the MyItem class and you can display whatever text you want. Hope this helps.
You shouldn't store data only in controls. I would create a class to hold all the info about a particular item, and populate THAT with the contents of the textboxes, and store it in some collection (Maybe a dictionary if you want to look one up by code)
You can then add a reference to this object in the "Tag" property of ListViewItem, so you can immediately grab it from any selected ListViewItem.
I dont quite understand what you mean by saying "can I somehow set all the data back into the textboxes by (that identifier) " which identifier ?!
but i would get data like this:
var item = listview1.items.where(x=>x.SubItems[0].value == mycodeId).firstordefault();
now i have the item i can retrieve data from it:
textbox1.Text = item[1].value;