Goal:
Get all file directories from MySQL and place them into a dictionary.
Display them into a combobox just as the filename. e.g. filename
Assign the combobox value as the the full directory. e.g. c:\users\user\desktop\filename.jpg
Code:
string filenames = "select filename from request_label_signoff where progress_user1 is null or progress_user2 is null";
//On load - load specific images from query above
private void Form15_Load(object sender, EventArgs e)
{
//Dict to store file into
Dictionary<string, string> files = new Dictionary<string, string>();
using (var conn = new MySqlConnection(connString))
{
conn.Open();
using (var cmd = new MySqlCommand(filenames, conn))
{
using (MySqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
//add filename without extension and full directory
files.Add(Path.GetFileNameWithoutExtension(reader.GetString(0)), reader.GetString(0));
}
}
}
}
comboBox1.DataSource = new BindingSource(files, null);
comboBox1.DisplayMember = "Key";
comboBox1.ValueMember = "Value";
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
value = ((KeyValuePair<string, string>)comboBox1.SelectedItem).Value;
pictureBox1.Image = Image.FromFile(value);
}
Problem:
For some reason the display value for the combobox shows like this:
Text output: [abc 123, C:\Users...]
Whereas it should be abc 123 without the directory next to it.
Question:
Why does he combo-box display value show both items?
You need to change the order of assignment in the combobox.
The reasons are:
sometimes the displaymember assignment wont work. From
StackOverflow Answer
comment.
Sometimes, selectedIndex event might fire if you set datasource first. Reference Stackoverflow
Answer
Instead of:
comboBox1.DataSource = new BindingSource(files, null);
comboBox1.DisplayMember = "Key";
comboBox1.ValueMember = "Value";
it should be:
comboBox1.DisplayMember = "Key";
comboBox1.ValueMember = "Value";
comboBox1.DataSource = new BindingSource(files, null);
Instead of using this: Dictionary<string, string> files = new Dictionary<string, string>();
I have used: var choices = new Dictionary<string, string>();
As guided in the comment by hans-passant
And everything works. Not sure what the difference was.
Related
I'm having some trouble trying to get the ValueMember value I've set. I'm trying to use a combobox to read XML data to textbox. Here's my code:
private void zamowienie_Load(object sender, EventArgs e)
{
label2.Text = DateTime.Now.ToShortDateString();
DataSet dsSet = new DataSet();
dsSet.ReadXml("E:\\baza\\spis_klientow.xml");
comboBox2.DataSource = dsSet.Tables["spis_klientow"];
comboBox2.DisplayMember = "ID";
comboBox2.ValueMember = "Name";
comboBox2.ValueMember = "Phone";
}
private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
{
DataSet ds = new DataSet();
ds.ReadXml("E:\\baza\\spis_klientow.xml");
foreach (DataRow item in ds.Tables["spis_klientow"].Rows)
{
label10.Text = item[1].ToString();
label11.Text = item[2].ToString();
}
}
When you bind a DataTable as ComboBox data source, the ComboBox.Items collection is populated with DataRowView objects. Then you can use ComboBox.SelectedItem like this
private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
{
var source = (DataRowView)comboBox2.SelectedItem;
label10.Text = source["Name"].ToString();
label11.Text = source["Phone"].ToString();
// ...
}
However, there is a better way. WinForms data binding infrastructure supports such scenario without a need to hook into a concrete control events. All you need is to bind combo box and text boxes to one and the same data source (DataTable in your case).
Here is a full working example of the data binding "magic" in action:
using System;
using System.Data;
using System.Windows.Forms;
namespace Samples
{
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var form = new Form();
var comboBox = new ComboBox { Left = 16, Top = 16, DropDownStyle = ComboBoxStyle.DropDownList };
var textBoxID = new TextBox { Left = 16, Top = comboBox.Bottom + 8 };
var textBoxName = new TextBox { Left = 16, Top = textBoxID.Bottom + 8 };
var textBoxPhone = new TextBox { Left = 16, Top = textBoxName.Bottom + 8 };
form.Controls.AddRange(new Control[] { comboBox, textBoxID, textBoxName, textBoxPhone });
// Begin essential part
var dataSource = GetData();
textBoxID.DataBindings.Add("Text", dataSource, "ID");
textBoxName.DataBindings.Add("Text", dataSource, "Name");
textBoxPhone.DataBindings.Add("Text", dataSource, "Phone");
comboBox.DisplayMember = "Name";
comboBox.ValueMember = "ID";
comboBox.DataSource = dataSource;
// End essential part
Application.Run(form);
}
static DataTable GetData()
{
//DataSet dsSet = new DataSet();
//dsSet.ReadXml("E:\\baza\\spis_klientow.xml");
//return dsSet.Tables["spis_klientow"];
var table = new DataTable();
table.Columns.Add("ID", typeof(int));
table.Columns.Add("Name");
table.Columns.Add("Phone");
for (int i = 1; i <= 10; i++)
table.Rows.Add(i, "Name" + i, "Phone" + i);
return table;
}
}
}
I was trying to add a default value ("--select item--") in existing ComboBox which is getting filled by Database table. Here is my code.
SqlConnection conn = new SqlConnection("Server = .\\SQLEXPRESS; Initial Catalog= Student; Trusted_Connection = True");
string query = "select Id, Name from abc1";
SqlDataAdapter da = new SqlDataAdapter();
conn.Open();
DataTable dt = new DataTable();
SqlCommand command = new SqlCommand(query, conn);
SqlDataReader reader = command.ExecuteReader();
dt.Load(reader);
comboBox1.DataSource = dt;
comboBox1.ValueMember = "Id";
comboBox1.DisplayMember = "Name";
Everything is working fine in above code and I'm getting CB filled with desired values.
Now when I try to insert default value using below, then it is throwing an error. This way was tried here
comboBox1.Items.Insert(0, "Select"); //this is throwing an error
comboBox1.SelectedIndex = 0;
I further explored below code to add default item.
comboBox1.SelectedIndex = -1;
comboBox1.Text = "Select an item";
This added an item as desired, but on any event, CB loses this value. After SelectIndexChanged event, I lose this value. So this cannot be my solution.
Any advise?
I'd rather not intefere into binding, but edit SQL instead:
string query =
#"select 0 as Id, -- or whatever default value you want
'select' as Name,
0,
union all
-- your original query here
select Id,
Name,
1
from abc1
-- to have default value on the top
order by 3 asc";
Insert's second parameter is expecting a ComboBox.ObjectCollection object.
Try doing this:
Having a class
public class ComboboxItem
{
public string Text { get; set; }
public object Value { get; set; }
}
And using:
// This could be inline, but for simplicity step by step...
ComboboxItem item = new ComboboxItem();
item.Text = "Item text1";
item.Value = 12;
comboBox1.Items.Add(item);
//or
comboBox1.Items.Insert(0, item);
You can add programmatically the item to the datatable
DataRow dr = dt.NewRow();
dr["id"] = "0";
dr["name"] = "Select";
dt.Rows.InsertAt(dr, 0);
then you can set the datasource
comboBox1.DataSource = dt;
If you just want to show a suggestion text to your user, the "EDIT" part of this answer may help (can only work if your ComboBox's DropDownStyle is not set to DropDownList).
But if you really want some "Select" item in your ComboBox, try this:
void Form1_Load(object sender, EventArgs e)
{
//load your datatable here
comboBox1.ValueMember = "ID";
comboBox1.DisplayMember = "Name";
comboBox1.Items.Add(new { ID = 0, Name = "Select" });
foreach (DataRow a in dt.Rows)
comboBox1.Items.Add(new { ID = a["ID"], Name = a["Name"] });
comboBox1.SelectedIndex = 0;
comboBox1.DropDown += new EventHandler(comboBox1_DropDown);
comboBox1.DropDownClosed += new EventHandler(comboBox1_DropDownClosed);
}
void comboBox1_DropDownClosed(object sender, EventArgs e)
{
if (!comboBox1.Items.Contains(new { ID = 0, Name = "Select" }))
{
comboBox1.Items.Insert(0, new { ID = 0, Name = "Select" });
comboBox1.SelectedIndex = 0;
}
}
void comboBox1_DropDown(object sender, EventArgs e)
{
if (comboBox1.Items.Contains(new { ID = 0, Name = "Select" }))
comboBox1.Items.Remove(new { ID = 0, Name = "Select" });
}
Please, I need some assistance. I have a C# form that has a listbox that I would like to fill during the form load event. When I click on an item, I would like for it to display relevant information in a few textboxes on the form, but the code below does not load the listbox. It does not err, but does not load any values either. I found a post similar to my request on this site, but it did not help.
Here is my code in the load section of a form:
string str = "Provider=Microsoft.Jet.OLEDB.4.0;DataSource=|DataDirectory|\\data.mdb;JetOLEDB:DatabasePassword=SomethingGoesHere";
OleDbConnection con = new OleDbConnection(str);
var ds = new DataSet();
var adapter = new OleDbDataAdapter("SELECT Last_Name FROM Membership_Log", con);
con.Open();
adapter.Fill(ds);
DataTable dt;
dt = ds.Tables[0];
View_Membership_Log_Listview.DataSource = dt;
View_Membership_Log_Listview.DisplayMember = "Last_Name";
var value = ds.Tables[0].Rows[0]["Last_Name"].ToString();
var value2 = ds.Tables[0].Rows[0]["First_Name"].ToString();
last_NameTextBox.Text = value;
first_NameTextBox.Text = value2;
con.Close();
Change:
View_Membership_Log_Listview.DataSource = dt;
View_Membership_Log_Listview.DisplayMember = "Last_Name";
var value = ds.Tables[0].Rows[0]["Last_Name"].ToString();
To:
Dictionary<string,string> d_Names = new Dictionary<string,string>();
foreach(DataRow row in ds.Tables[0].Rows)
{
d_Names.Add(row["Last_Name"].ToString(),row["Last_Name"].ToString()); //Last name is the key, First name could be used as the value or visa versa if needed.
}
View_Membership_Log_Listview.DataSource = d_Names;
View_Membership_Log_Listview.DisplayMember = "Key";
View_Membership_Log_Listview.ValueMember = "Key";
Hope this helps, I dont have VS open infront of me so please forgive any mistakes.
How do i set this values? I have a DataTable with all the data i want to set in the combobox, but i cant find how to set it.
I tried
ComboBox1.DataSource = dataTable;
ComboBox1.ValueMember = "id"; // --> once hes here, he just jumps out the method
ComboBox1.DisplayMember = "name";
No compilation error, warning, nothing.. just jumps out!
This is the query to fill the DataTable
"Select * from \"Table\""
I checked with the debugger and the datatable was filled. The columns names are "id" and "name". ComboBox is blank. I'm filling it for the first time!
You should not set datasource of your listbox and/or combobox in this order
ComboBox1.DataSource = dataTable;
ComboBox1.ValueMember = "id";
ComboBox1.DisplayMember = "name";
Instead, this is correct order:
ComboBox1.ValueMember = "id";
ComboBox1.DisplayMember = "name";
ComboBox1.DataSource = dataTable;
NOTE: setting datasource should be last line.
If you set datasource first, SelectedIndexChanged event will fire and you may get the cast error or other exception.
Using keyvalue pairs to populate a combobox
A neat way to populate combo boxes is to set the datasource to a list of keyvalue pairs. It may also inspire using data stored in a list of some kind:
//Some values to show in combobox
string[] ports= new string[3] {"COM1", "COM2", "COM3"};
//Set datasource to string array converted to list of keyvaluepairs
combobox.Datasource = ports.Select(p => new KeyValuePair<string, string>(p, p)).ToList();
//Configure the combo control
combobox.DisplayMember = "Key";
combobox.ValueMember = "Value";
combobox.SelectedValue = ports[0];
The datasource can be populated using this syntax as well:
ports.Select(p => new { Key = p, Value = p }).ToList();
The technicue may be expanded with more property names for multiple column lists.
Objects that are already key-value pairs like Dictionary items can be used directly
combobox.DataSource = new Dictionary<int, string>()
{
{0, "COM1"},
{1, "COM2"},
{2, "COM3"},
}.ToList();
combobox.ValueMember = "Key";
combobox.DisplayMember = "Value";
Tuples can be initialized and used like this
var ports= new List<Tuple<int, string>>()
{
Tuple.Create(0, "COM1"),
Tuple.Create(1, "COM2"),
Tuple.Create(2, "COM3")
};
combobox.DataSource = ports;
combobox.ValueMember = "Item1";
combobox.DisplayMember = "Item2";
ComboBox1.DataSource= dt; //the data table which contains data
ComboBox1.ValueMember = "id"; // column name which you want in SelectedValue
ComboBox1.DisplayMember = "name"; // column name that you need to display as text
They take strings...
ComboBox1.ValueMember = "id";
ComboBox1.DisplayMember = "name";
I had the same trouble. In my case, SelectedIndexChanged event fires and just jumps out the method. Try do not use SelectedIndexChanged event. Or something like this:
ComboBox1.SelectedIndexChanged -= new System.EventHandler(ComboBox1_SelectedIndexChanged);
ComboBox1.DataSource = dataTable;
ComboBox1.ValueMember = "id";
ComboBox1.DisplayMember = "name";
ComboBox1.SelectedIndexChanged += new System.EventHandler(ComboBox1_SelectedIndexChanged);
It worked for me. =)
ComboBox1.ValueMember = dataTable.Columns["id"].ColumnsName; // column name which the values are not visible
ComboBox1.DisplayMember = dataTable.Columns ["name"].ColumnsName;
/*
column name that you need to select item by proprity :
ComboBox1.SelectedItem;
Or you can use easly this :
ComboBox1.Text;
*/
ComboBox1.DataSource= dataTable; //the data table which contains data
// and this should be last :)
public class ComboDeger {
private string yazi;
private int deger;
public ComboDeger(string stryazi, int strdeger) {
this.yazi = stryazi;
this.deger = strdeger;
}
public string yazisi {
get {
return yazi;
}
}
public int degeri {
get {
return deger;
}
}
}
private void combobox_doldur() {
ArrayList ComboDegerleri = new ArrayList();
ComboDegerleri.Add(new ComboDeger("9 : NORMAL", 9));
ComboDegerleri.Add(new ComboDeger("10 : ENGELLÄ°", 10));
comboBox1.DataSource = ComboDegerleri;
comboBox1.DisplayMember = "yazisi";
comboBox1.ValueMember = "degeri";
}
private void Form3_Load(object sender, EventArgs e) {
con.Open();
combobox_doldur();
// Populate the COMBOBOX using an array as DataSource.
}
you could specify like this
ComboBox1.ValueMember = "id";
ComboBox1.DisplayMember = "name";
i have a combobox whose datasource is a datatable. i need to loop through the items in the combobox, but how would i do this? i need to be able to convert each object of type 'System.Data.DataRowView' to string. any advice greatly appreciated!#
Based on your recent questions, it sounds like you are trying to figure out how to find or set the selected item in the combobox based on the text displayed in the item. I am not exactly sure how you have things set up, but please look at the following code and see if it helps:
private void button1_Click(object sender, EventArgs e)
{
DataTable dt = new DataTable();
dt.Columns.Add("ID", typeof(int));
dt.Columns.Add("Name", typeof(string));
dt.Rows.Add(1, "A");
dt.Rows.Add(2, "B");
dt.Rows.Add(3, "C");
comboBox1.DataSource = dt;
comboBox1.DisplayMember = "Name";
comboBox1.ValueMember = "ID";
// use SelectedValue to select the item with ID == 2
comboBox1.SelectedValue = 2;
// use FindStringExact() to find the index of text displayed in the item
comboBox1.SelectedIndex = comboBox1.FindStringExact("C");
}
and using a combobox as set up above, you can get the text of the display member like this:
private void button2_Click(object sender, EventArgs e)
{
foreach (var item in comboBox1.Items)
MessageBox.Show(((DataRowView)item)["Name"].ToString());
}
Workaround for the same, hope it helps:
Convert the dataview source back to datatable and then loop through it.
DataView dt = (DataView)comboBox1.DataSource;
DataTable s = dt.Table;
foreach(DataRow dr in s.Rows)
MessageBox.Show(dr[0].ToString());
Well... to loop through a combobox, use (slightly pseudocoding, please don't c+p without working on the code):
var newItems = new List<string>();
for(var i = 0; i < combobox1.Items.Count; i++)
{
newItems.Add(combobox1.items[i].Text);
}
Then to access each item, use:
foreach(item in newItems)
{
var newVariable1 = item;
}
More info and your current code would be cool, I'd be able to help you more specifically with your problem that way.
Solution:
DataTable DtShow=new DataTable();
for (int i = 0; i < DtShow.Rows.Count; i++)
{
Console.WriteLine(DtShow.Rows[i].Field<string>(0));
}
** Field<string>(0) Column number start from 0
Hope this helps someone some day. Took me a while to come up with a solution for making a checkedboxlist populate from SQL server.
public partial class MemberSearch : Form
{
List<string> DataList = new List<string>(1);
public void GetTypesTable()
{
var CONEX = Properties.Settings.Default.Server_1_Conn;
var sql = "SELECT Type_List FROM List_Member_Types;";
DataTable dt = new DataTable();
using (SqlConnection c = new SqlConnection(CONEX))
using (SqlDataAdapter sda = new SqlDataAdapter(sql, c))
sda.Fill(dt);
DataView view = new DataView(dt);
DataTable s = dt;
foreach (DataRow ROW in s.Rows)
DataList.Add(ROW[0].ToString());
ckLstBox_MemTypes.DataSource = DataList;
}
}