C#: Trouble going from combobox to dropdownlist - c#

I am still very new to programming, as im sure my question will show. I have spent the past two days utterly stuck, and i have not been able to find the answer to this anywhere. Might be because im just overlooking something so obvious that no one has had to ask, but here it goes:
I have made an application in VS Express 2013 for windows where the user chooses an alternative from a combobox displaying only the name of the object. From the choice i send the whole object to my "Converter Class".
EU = new Converter("Enriched Uranium", "44");
CO = new Converter("Coolant", "9832");
BI = new Converter("Biocells", "2329");
CB = new Converter("Construction Blocks", "3828");
FR = new Converter("Fertilizer", "3693");
GL = new Converter("Genetically Enhanced Livestock", "15317");
object[] myArray1 = { EU, CO, BI, CB, FR, GL };
comboBox1.DisplayMember = "name";
There are around 50 of these in the program. The first part is the name, the other is the ID that the XML uses to find stuff. They perform lots of stuff further on in the code, but this is the start:
Converter a = ((Converter)comboBox1.SelectedItem);
a.CallXml();
a.taxPrice(comboBox2.Text);
a.getNumber(textBox4.Text);
a.getTax(taxrat);
And so on... I know its not exactly beautiful, and i am seeing a lot of ways to make it more effective after learing. But right now im focusing on converting the whole thing to a web site, and im using VS Express 2013 for Web.
There is no combobox there, so im stuck using dropdownlist. The above method of loading the list with "AddRange" did not work, and ive trid about a hundred things, until i finally get to display the names this way:
List<object> myList1 = new List<object>();
myList1.Add(EU);
myList1.Add(CO);
myList1.Add(BI);
DropDownList2.DataSource = myList1;
DropDownList2.DataTextField = "name";
DropDownList2.DataBind();
So far so good! Where i am now utterly stuck is at the point where i need the users choice to return the object and send it to the "Converter" class. This is the closes i feel ive come:
protected void Button1_Click(object sender, EventArgs e)
{
object a = (Converter)DropDownList2.SelectedItem;
}
It says: "Cannot convert type blablabla to WebApplication4.Converter. How come? And is there any way i can make it to perform the same action the combobox did back in good, old winform?
What i want to do is that when the user chooses "Enriched Uranium", the program calls the "Converter class" with for example:
EU.CallXml();
And so on.

Welcome to the world of web development and the whole stateless request / response mechanism. To understand this fully have a read up on the differences between windows and web development.
In webforms the controls are a lot more basic than the winforms ones. Really the binding is just one way - its just using your source data to get the info needed to draw the list. If you think about it it has to be like this, otherwise it would be having to pass your entire list of objects between the server and the clients browser which would be wasteful, and its hard in a stateless environment to know when to bind back etc.
The webforms Dropdownlist.SelectedItem is of type ListBoxItem - which just has the minimum fields needed to draw and get the item from the dropdownlist control - just the text from the ListItem, and whether its selected. Which is why you can't cast it back to your converter object.
So how can you get map the selected item back to your Converter? You can either use the string value Dropdownlist.SelectedItem.Value to do some sort of lookup, or use the Dropdownlist.SelectedIndex to find the item from your source list at that index.
You could do something like this
List<Converter> myList1 = GetConverters(); //todo - write a method to make the list
DropDownList2.DataSource = myList1;
DropDownList2.DataTextField = "name";
DropDownList2.DataBind();
and on the click event
protected void Button1_Click(object sender, EventArgs e)
{
string s = DropDownList2.SelectedItem.Value;
Converter c = GetConverters().Find(x => x.name == s);
//do whatever with the converter
}
disclaimer - none of this is compiled - so may have some errors. Also its definitely not the best way of doing it (no error checking + making the list of converters just to do the datasource bind is a bit wasteful), just to show you how it could be done.
One other warning - make sure you only do the datasource bind once - its possible if you do it without a check that the page hasn't posted back it could bind just before you try to get the value - meaning the first value will always seem selected. Good luck!

Related

How to keep all date selection in calendar?

I've created a code that read dates from a database and put them into the Calendar control. All working good, but if the user select a date in the Calendar, after the population, all the date selected through code disappear. There's another way to flag the date that are previously added from the database population?
public void setFixturesControl()
{
Database.m_dbConnection.Open();
string query = "select * from date";
SQLiteCommand input = new SQLiteCommand(query, Database.m_dbConnection);
SQLiteDataReader reader = input.ExecuteReader();
while (reader.Read())
{
if (MainWindow.AppWindow.League.SelectedItem.ToString().Equals(reader["caption"].ToString()))
{
MainWindow.AppWindow.Calendar.SelectedDates.Add(DateTime.Parse(reader["data"].ToString()));
}
}
Database.m_dbConnection.Close();
}
There's a way to prevent the dates disappear after a user click? Or something that allow me to recognize the dates added by database population? Thanks.
After a long search on the net and a large documentation on the Calendar class, I could see two things:
To get what I want I have to take advantage of a custom control
Try to act via code by creating a delegate, but this is not really a
simple thing
I ran then in the first point, in particular, from the post of David Veeneman, it addresses exactly my problem.
The final result will be like this:
Exactly what I want.
In the post it is all documented, so it would be pointless to do a copy paste here. Thank this member that for me at least was able to solve a failure in the control of Microsoft. Unfortunately I am increasingly convinced that WPF is still immature and that still requires a bit 'of years to complete. I hope my answer is help, if anyone manages to solve the problem in a more elegant, well it responds well. Thank You.

TweetSharp: How do i display username net to the users name in my listView?

Hello im currently trying to fix so that my listview displays 2 columns, one which displays the tweet and the second one displaying the tweets owner(the user). how do i do this? i've come this far:
private void button1_Click(object sender, EventArgs e)
{
listbox1.Items.Clear();
tweetid.Items.Clear();
TwitterSearchResult inc = service.Search(new SearchOptions { Q = "stuff", Lang = "en" });
IEnumerable<TwitterStatus> status = inc.Statuses;
foreach (var tweet in inc.Statuses)
{
ListViewItem item = new ListViewItem(tweet.Text);
item.SubItems.Add(tweet.Text);
item.SubItems.Add(tweet.Text);
listView2.Items.Add(item);
I sorta want to include a new Tweetsharp command in the same variable "tweet". Is this possible. im thinking i have to add a new IEnumerable<>.
Any help would be thankfully accepted.
OH AND ONE MORE THING! :)
How come that tweetsharp only returns a 100 tweets max? Is there a way to solve this too? :)
Thanks.
one which displays the tweet and the second one displaying the tweets owner(the user)
Well, taking a quick look at the objects you're using, it appears that TwitterStatus has a User property of type TwitterUser, which itself has a Name property. Does the intellisense disagree with this?
im thinking i have to add a new IEnumerable<>
Why? You currently have a collection of TwitterStatus objects, which seem to contain all the information you need. Are you just looking to do this?:
item.SubItems.Add(tweet.Text);
item.SubItems.Add(tweet.User.Name);
From that collection (IEnumerable<>) of TwitterStatus objects you are able to extract all the information about those tweets. Just display the information you want to display.

convert value to datatype in string format

I an c# beginner and working in web development using Silver Light-5 in Visual Studio-2010. I have my GUI on running my code which has it's GUI created by xaml and the button clicks are handled in c#.
Now what i have to achieve is :
I am trying to create a GUI in which i use combo box which will contain options like this (please see this link) http://prntscr.com/36l58s In this link i select the one datatype among the 5 given datatypes (which are byte,sbyte,short,int,long). And after that i want to assign this datatype to a variable in c# code like this: (suppose i selected "short" in that).
then i want to assign it to a variable (suppose "varble" here) like this short varble =1000;
How to do that ?
My xaml code for it is :
and c# code for it is (Inside the constructor) :
comboBox1.Items.Add("byte");
comboBox1.Items.Add("sbyte");
comboBox1.Items.Add("short");
comboBox1.Items.Add("int");
comboBox1.Items.Add("long");
and button click event of ComboBox is :
private void comboBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
}
Why i am trying to do this? :
Actually ,i was just trying to create a GUI where i can select the datatype of variable at run time among the given specified options and i guess using combobox is best suitable. This selected dataType (for example short in previous example) that selected dataType i then assign to a variable in my code in c#.(Actually i am reading i binary file and i have to select the byte read to store in a variable which must have options of dataType (like short,int,long) in 16/32/64 bit integer which is supposed to be selected by COMBO Box). Could you please help me in doing that ? Thanks a lot (If my logic don't work and you have other alternative then please tell me with full details because i am just a beginner). Thanks again
You can get idea from below code sample :
var selectedDatatype = "String";
var valueToConvert = 1;
var convertedValue = Convert.ChangeType(valueToConvert, Type.GetType("System." + selectedDatatype));
Note: make sure that items populated in dropdown belongs to System namespace. So instead of long you should use Int64

"All" value for a Combobox Data Filter in WPF

During the construction of user control I populate the combobox with some data. Works fine. I have Status.ID as valuePath and Status.Name as displayPath.
cmb.ItemsSource = dbEntities.Status
The comobox will be used as a filter control and I need to insert some value for "All", which will be used as the empty filter.
First I tried a funny solution:
ObjectSet objectSet= dbEntities.Status;
Status stAll = new Status();
stAll.ID = -1;
stAll.Name = "All";
objectSet.AddObject(stAll);
cmb.ItemsSource = objectSet;
For some reason the object is not added to the objectSet. It didnt throw any exception either.
Then I tried to insert it manually to the first index but I got the error:
"Operation is not valid while ItemsSource is in use. Access and modify elements with ItemsControl.ItemsSource instead."
My code looked like:
cmb.ItemsSource = entities.Status;
cmb.Items.Insert(0,"All");
Both didnt work. What would be the easiest way to add that line to the combobox? The error message got me confused. I am not sure how to use the ItemsSource for such a purpose.
edit: I did not have enough rep to answer my own question so here is the working code. Thanks Craig again.
CompositeCollection comp = new CompositeCollection();
comp.Add(new CollectionContainer {Collection = dbEntities.Status});
Status stAll = new Status();
stAll.ID = -1;
stAll.Name = "All";
comp.add(stAll);
cmb.ItemsSource = comp;
//do whatever filter you want when the selected value is -1
There are a couple different problems with what you are trying to do. You can't manipulate the Items when you are using the ItemsSource, instead you have to go through the object that is set to the ItemsSource. That is what the error message is about in the second part. Its because when you set the ItemsSource the Items value is unused it is not populated with the values of the ItemsSource.
I'm not familiar enough with the ObjectSet class to know why the first case is not working. However, it seems awkward to add an item to your values you are pulling from somewhere else, just to have the all case. The better solution is to use a null value to represent nothing. Unfortunately, there is no built in way to do this in WPF. However, there is a fairly easy solution of using an Adaptor do do this. I have used this solution a NullItemSelectorAdaptor, that enables null as a selection even if null is not in the list. All you have to do is wrap your combobox in the NullItemSelectorAdapter and null will be added as a value. The blog post explains everything pretty clearly, so I won't repeat it. You than can setup your filter so that null equates to no filtering.

How to access a cell in a DataRowView based on the columns DataPropertyName?

I have a Windows Forms application with a DataSet. I've simply used the Data | Add New DataSource to add the Products table of the Northwind database to my DataSources and created a DataGridView showing the contents of the Products table. I just dragged the Products table from the Data Sources window to the form, so all the columns are created automatically.
Now, I want the rows containing a product where the Discontinued column is true to be painted in a different color. I've created a CellPainting event handler for it, but I'm having trouble locating the value for the Discontinued column.
Because the DataGridView is created automatically, the Columns in it have names like dataGridViewTextBoxColumn1, which has a DataPropertyName of "ProductID".
My question is: how can I find the value for Discontinued based on the DataPropertyName? Or am I required to use the name of the column itself? (In which case I better give it a meaningful name)
My code is:
private void productsDataGridView_CellPainting(object sender,
DataGridViewCellPaintingEventArgs e)
{
if (e.RowIndex >= 0)
{
var row = productsDataGridView.Rows[e.RowIndex];
if ((bool) (row.Cells[ nameOrIndexOfColumn ].Value))
{
e.CellStyle.ForeColor = Color.DarkGray;
}
}
}
How can I access the Value of the Column with DataPropertyName "Discontinued"?
Solution
Based on Neil Barnwell's answer, this seems to be a way.
private void productsDataGridView_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if (e.RowIndex >= 0)
{
var productView = (DataRowView) productsDataGridView.Rows[e.RowIndex].DataBoundItem;
var product = productView.Row as NorthwindDataSet.ProductsRow;
if (product != null && product.Discontinued)
{
e.CellStyle.ForeColor = Color.DarkGray;
}
}
}
The big advantage of this is that the Discontinued value doesn't have to be an actual column on the DataGridView.
Don't get the value from the column in the grid, get the value from the actual datarow that populates the gridrow. This way you can avoid all the magic strings etc.
There's a little bit of casting to be done because the [Type]DataRow is hidden inside a DataView that's attached to the grid, but it is a more elegant approach (and far less brittle in case of future changes) if you integrate it nicely into your code than relying on magic strings.
Here's an old blog post of mine that describes in detail how to do it:
http://koder.wordpress.com/2010/04/09/getting-data-from-a-winforms-datagridview/
UPDATE
You've mentioned that you're using Northwind and that you've "simply dragged the Products table to the form", so I'm guessing this isn't a mission-critical piece of software, but for the benefit of other people reading, I just wanted to suggest that this wouldn't be a typical approach any more in a real application.
Typically these days we'd consider having a Domain Model, perhaps using an ORM to obtain our Domain Objects from the data store (of course datasets aren't a real ORM), then possibly using things like MVVM to build data structures optimised for binding to UI elements from those Domain Objects.
Using this approach, because you have the actual data to hand in your ViewModel, you can calculate such rules as colours etc from the real data, and the UI simply displays the results of applying those business rules.
Why don't you try giving a name to that particular column yourself and then you know how to access it. Visual studio shouldn't have any problem with this even if its auto generated. Because it was generated to help you do all the binding and column creating stuff in the background. But it is still available for editing, autogenerated doesn't mean it generated at run-time . Its just helping you do the usual stuff, but you can still edit it.
row.Cells[ nameOrIndexOfColumn ]
You can try something on these lines
if (dataGridView1.Columns[e.ColumnIndex].DataPropertyName == "Discontinued")
{
if (dataGridView1[reqdColumnIndex, e.RowIndex].FormattedValue as bool)
{
e.CellStyle.ForeColor = Color.Gray;
}
}
reqdColumnIndex is the column which has your bool value

Categories