I have a code that reads the information from the database and assigns it to the list
class YaziciBilgiler
{
public string yaziciAdi;
public List<YaziciBilgiler> YaziciSec()
{
con.Open();
OracleCommand cmd = new OracleCommand("SELECT PRINTER_NAME FROM LABEL_PRINTER ");
DataSet dataset = new DataSet();
cmd.Connection = con;
cmd.CommandType = CommandType.Text;
using (OracleDataAdapter dataAdapter = new OracleDataAdapter())
{
dataAdapter.SelectCommand = cmd;
dataAdapter.Fill(dataset);
}
var yazici=dataset.Tables[0].AsEnumerable().Select(datarow=>new YaziciBilgiler
{
yaziciAdi = datarow.Field<string>("PRINTER_NAME")
}).ToList();
con.Close();
return yazici;
}
}
}
Then call the information in the printer list from the form
List<YaziciBilgiler>yazici;
yazici=yb.YaziciSec();
foreach (var item in yazici)
{
cbYazici.Items.Add(item);
}
but instead of the contents of the list, the location is as follows:
The basic problem with your code is that you have created a list full of objects with type YaziciBilgiler with a single string member called yaziciAdi
Combo doesn't know how to display this, it doesn't know to get the yaziciAdi property and show it, and you haven't told it so the only thing it can do when faced with an unknown object is call ToString() on it to get a string and display that string
Because you haven't overridden ToString it performs its default action which is to report the name of the class. This means your combo is full of repeated words of YaziciBilgiler
You have a few options:
override ToString so that it returns the yaziciAdi property
make your code that adds the items inside the loop add the yaziciAdi property instead of the whole object: cbYazici.Items.Add(item.yaziciAdi);
change the yaziciAdi member to be a property instead. bind the combobox to the list, or to the datatable- the discussion for this is in the comments to the question. I don't use WPF but reading around, I think the code might be something like:
cbYazici.SetBinding(
ItemsControl.ItemsSourceProperty,
new Binding { Source = yazici });
cbYazici.DisplayMemberPath = "yaziciAdi";
Or use an equivalent in the XAML (if the codebehind can't set these; I've no idea whether it can or not, and any experienced WPF guys feel free to edit this answer if I've got this wrong)
Note: to bind property yaziciAdi MUST be a property, not a field
You can try this :
cbYazici.Items.Add(item.yaziciAdi)
Related
I'm fairly new to C#, so please bear with me. I have a class FixData:
private class FixData
{
public int ID { get; set; }
public List<string> content { get; set; }
}
And there's also private List<FixData> IDList = new List<FixData>();
I'm querying data from sql database using IDs already stored in IDList andSqlDataReader and then trying to save it into IDList.content. But that's where the hard part starts. I don't really know how many rows or columns this data has and trying to read that from debugger made me so much more confused (in other words: I fail to read it). Despite this, I tried to save it in so many ways and so many times that I'm completly lost at this point. Here's the code:
foreach (var record in IDList)
{
SqlCommand nonQuerycmd = new SqlCommand(NonQuery, connection);
nonQuerycmd.Parameters.Add(new SqlParameter("ScenarioID", record.ID));
nonQuerycmd.ExecuteNonQuery();
SqlCommand cmd = new SqlCommand(FixQuery, connection);
sqlreader = cmd.ExecuteReader();
ArrayList rowList = new ArrayList();
while (sqlreader.Read())
{
object[] values = new object[sqlreader.FieldCount];
sqlreader.GetValues(values);
rowList.Add(values);
record.content = values.Cast<object>().Select(x => x.ToString()).ToList();
}
sqlreader.Close();
}
Could you please help me and point me to an explanation or link or something that could help me understand how I should solve this?
Edit
I've managed to scramble something, but I'm not sure if this works as it was intended to.
Take a look at the MSDN documentation for SqlDataReader class. It should get you started.
The examples and other classes linked to there should help with proper usage of SqlCommand and other classes as well.
Without knowing what's in your table, the best I can do is:
if (read.Read())
{
for(int i = 0; i < read.FieldCount; i++)
{
record.content.Add(Convert.ToString(read[i]));
}
}
This will add every field selected to record.content as a string. I just changed "while" to "if" because you will only be handling one row (I think). If you need more help, let us know more information about your data and what you need. If, for some reason, you are putting multiple fields from multiple rows, use while. If you only want one field from multiple rows, change if to while, take out the for/next and change [i] to [0]. Shannon is not Carnac the Magnificent.
When I want to put the values in an array that are selected from a checkedlistbox. And then say:
messagebox.show(values[0]);
It's saying : System.Data.DataRowView
This is my current code:
string[] itemArr = new string[clbTables.CheckedItems.Count];
int counter = 0;
foreach (object item in this.clbTables.CheckedItems)
{
string temp = Convert.ToString(item);
itemArr[counter] = temp;
counter++;
}
MetroMessageBox.Show(this, itemArr[0].ToString());
What am I doing wrong here>?
EDIT ::
clbTables.DataSource = sqlDisplayContent.connectDataTable("SELECT ('Tafelnr: '+ CONVERT(varchar,tafelnr)+' Zitplaatsen: '+ CONVERT(varchar,zitPlaatsen)) AS dispValue,tafelnr FROM tabel");
clbTables.DisplayMember = "dispValue";
clbTables.ValueMember = "tafelnr";
class sqlDisplayContent
{
public static DataTable connectDataTable(string query)
{
SqlCommand comm= sqlCrud.returnSqlCommand(query);
SqlDataAdapter sda = new SqlDataAdapter(comm);
DataTable dt = new DataTable();
sda.Fill(dt);
return dt;
}
}
Thankss
The issue is that:
Convert.ToString(item);
will simply call the ToString() method of the object and store that, which in this case, is giving you the object's type. In this case, the type is System.Data.DataRowView. I suggest that you access the specific field in the row that you want by using:
((DataRowView)item).Row["FieldName"].ToString();
instead. You will want to replace "FieldName" with whatever the name of your column that you are wanting is. Additionally, you can use an int index instead of a string reference. Of course, if you need to access multiple fields, you can do this by simple string concatenation. The issue is that you need to access the specific field that you want. Not the entire row as you are currently on.
I hope this helps!
A couple references: DataRow, DataRowView
I suppose that your values[] array is not right. Please, refer to this example on MSDN.
https://msdn.microsoft.com/en-us/library/system.windows.forms.checkedlistbox.checkeditems(v=vs.110).aspx
string temp = ((CheckBox)item).Text;
You are passing in the object, not the object's text (which is what it seems you want the code to do).
I've seen a few similar questions to this issue I'm having, but they all don't seem to work out.
I currently have a method that populates an arraylist with items from a database query, and then returns the arraylist to be used to populate a ComboBox. The ComboBox will be used as a search filter for additional database queries.
I'd like to add a null value to the arraylist in order to allow for the user to "turn the filter off" when the null value is selected.
The issue comes up when adding the null value to the array list. When I add the null value before the database items are added, all of the items don't show up in the actual ComboBox. When I add the null value after the ArrayList has been populated, the null value never shows up as a row in the ComboBox, but everything else is there.
public static ArrayList DropDown()
{
ArrayList status = new ArrayList();
connect.Open();
// Finds the stuff to use in the COMBO BOX
cmd.CommandText = String.Format("query");
reader = cmd.ExecuteReader();
while (reader.Read())
{
status.Add(String.Format("{0}", reader[BANK_ID]));
}
string holder = null;
status.Add(holder);
connect.Close();
return status;
}
This results in the populated ComboBox, but no null row.
public static ArrayList DropDown()
{
ArrayList status = new ArrayList();
string holder = null;
status.Add(holder);
connect.Open();
// Finds the stuff to use in the COMBO BOX
cmd.CommandText = String.Format("query");
reader = cmd.ExecuteReader();
;
while (reader.Read())
{
status.Add(String.Format("{0}", reader[BANK_ID]));
}
connect.Close();
return status;
}
This results in nothing in the combo box.
Thanks for the help!
The items collection of a combobox can not contain null. Refer:
http://msdn.microsoft.com/en-us/library/system.windows.forms.combobox.objectcollection.add.aspx
I assume setting DataSource is internally checking for this and hence the behavior that you have noted (probably a more informed person can confirm this)
I suggest you add String.Empty instead and you can get rid of arraylist all together and use a string array/list instead.
comboBox.Items.Insert(0, string.Empty);
This is what i am trying to do. I have a database that i am reading from using the code:
OleDbCommand command;
command = new OleDbCommand("SELECT " + Student.ID + " FROM " + newStudent.DataFile, conn);
conn.Open();
dt.Load(command.ExecuteReader());
conn.Close();
I then have the datatable bind to a datagridview and display the contents of the table.Now the problem is, i have more information to add to the datatable dt that is not in the database. For example, i have a field for the student object called Grade that is not found in the datafile but entered in by the user and stored in a property for the student object.
Instead of loading the query result into a datatable, is there a way to load it into a list so i can manually create rows and columns for a datatable in another method and then add the contents of the list(containing id) and the grade information in the student object manually?
If you don't fancy going for a full blown ORM framework such as the one #Bas has suggested...
Take a look at the ToTable method available from on a Datatable's Dataview. You can get the DataView for your Datatable simply using DataTable.DefaultView:
List<Long> myList = dt.DefaultDataView.ToTable(True, "ID").AsEnumerable().ToList()
myList.Add(1234)
//etc
Alternatively, you can load the additional data you want to append into a second datatable, and use the DataTable.Merge Method
EDIT: To account for wanting to add additional columns, you can change the above list suggestion as follows:
// Create a class to hold the information you want to bind,
// you could use anonymous types if preferred
class MyDataRow
{
public long ID { get; set; }
public string AnotherColumn { get; set; }
public string AndAnotherColumn { get; set; }
}
// then later on when creating that list use something along the lines of:
List<MyDataRow> myList = dt.DefaultDataView.ToTable(True, "ID").AsEnumerable().Select(x => new MyDataRow { ID = x.ID }).ToList()
// you now have a list of MyDataRow which you can work with
// for example...
if (myList.Any())
myList.First().AnotherColumn = "foo";
// as an exmaple of using an anoymous type (not my preference, but an option nonetheless)
var anonymousList = dt.DefaultDataView.ToTable(True, "ID").AsEnumerable().Select(x => new { ID = x.ID, whateverYouWantToCallIt = "some other data but this is read only property" }).ToList()
// you can work with the anonymous list in much the same way, it just isn't explicitly declared
// and the properties are Read Only
if (anonymousList.Any())
Console.WriteLine(anonymousList.First().whateverYouWantToCallIt);
You could use Entity Framework to extract an object model from your database. Afterwards you could add the property for grade to your object (due to the fact that these objects are created in partial classes). This provides a (vastly) more structured / easy to use way of adding custom logic and attributes to your data structure.
You can bind your GUI components to entity framework objects in a similar way as you would using conventional ADO.NET.
I want to create a winforms app where you can assign tags to an entity.
ofc I want the customer to re-use existing tags a lot. That's why I want
to show them the list of tags while they are typing (similar to intellisense
in VS and the tags-dropdown even here in stackoverflow ;))
do you have any control(s) in mind that offers this functionality?
can I reuse a ComboBox for this? (here I need to drop it down programatically - how?)
I want to have the taglist getting input-focus but not lose the mainform-focus,
and I want it to be on top over all windows and even range out of the mainform-area
(like intellisense in vs)
thx!
Here I have made a function to which pass the table name from which auto-complete has to be done, name of the field which needs to be auto-complete and the combobox which needs to be targeted.
Try the following code:
public void AutoCompleteTextBox(string tableName, string fieldName, ComboBox combToAutoComp)
{
AutoCompleteStringCollection txtCollection = new AutoCompleteStringCollection();
DataTable dtAutoComp = Dal.ExecuteDataSetBySelect("Stored_Procedure", fieldName, tableName);
if (dtAutoComp.Rows.Count >= 0)
{
for (int count = 0; count < dtAutoComp.Rows.Count; count++)
{
txtCollection.Add(dtAutoComp.Rows[count][fieldName].ToString());
}
}
combToAutoComp.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
combToAutoComp.AutoCompleteSource = AutoCompleteSource.CustomSource;
combToAutoComp.AutoCompleteCustomSource = txtCollection;
}
Here Dal.ExecuteDataSetBySelect is my implementation where i create the connection, command and dataadapter for calling the stored-procedure. You can replace it with your own implementation for the same. For more refer this link