Working with listbox in winforms (c#) - c#

How can i add 10 items to listbox dynamically to a listbox and after that I want to show the selected item value in click event of list box.
I tried like this
for(int i=1;i<10 ;i++)
{
mylistbox.Items.Add(i.ToString());
}
in click event handler
MessageBox.Show(mylistbox.SelectedValue.ToString());
it is showing error.
Whats the wrong with this?

Try using the SelectedItem property instead.
SelectedValue only works when you fill the ListBox with objects and have a ValueMember assigned.
Here is a minimal example:
var mylistbox = new ListBox {Dock = DockStyle.Fill};
mylistbox.Click += (sender, e) =>
MessageBox.Show(mylistbox.SelectedItem.ToString());
for (int i = 1; i < 10; i++)
{
mylistbox.Items.Add(i.ToString());
}
new Form {Controls = {mylistbox}}.ShowDialog();

Use the following code on the click handler
MessageBox.Show(mylistbox.Text.ToString()); //This will show the selected item as your requirement.
replace the .SelectedValue with .Text

Dmitriy has it exactly.
A good way to check what is happening when you're debugging is to highlight 'mylistbox.SelectedValue' and right-click, then select 'Add Watch'. You can then track the value of that property in the Watch window.
You can do this with any variable, and any time it shows null and you're trying to use that value you know it will throw a Null Reference Exception.
It's also good for picking up letters in a string you're trying to convert to an integer, and other similar "d'oh!" moments.

Related

WPF drop-down list for auto generated column in datagrid

How to make a drop-down list when you click on an element of a specific table column in which you can select an element for this cell? Column is auto generated.
A Combobox in xaml/wpf is used like this:
<ComboBox x:Name="some Name" SelectionChanged="comboboxChanged">
<ComboBoxItem>The Content of your Combobox</ComboBoxItem>
</Combobox>
ComboBoxItems are essentially the dropdown part. You can add as many as you want.
In your back end (c#) you can get the selected Value as soon as the "SelectionChanged"-event is triggered. The code for getting the selected Value can be done multiple ways. Example:
private void comboboxChanged(object sender, SelectionChangedEventArgs e){
string comboboxvalue = comboboxname.Text;
//Then set associated textblock or label
labelname.Content = comboboxvalue;
}
The code above would be static though. Dynamically generating these elements could look like this for instance.
When auto-generating, using an inline function for the event is easy.
for (int i = 0; i < 10; i++){
ComboBox comboboxname = new ComboBox();
comboboxname.SelectionChanged += (ss,ee) { string comboBoxValue = comboboxname.Text; labelname.Content = comboBoxValue;}
}
Labelname being the name of the Label you want to set. In that loop you will need to implement a way of giving each box a unique name and getting the name of the associated label in there as well. That you will have to figure out on your own as i do not know how and what exactly is generated and what is static.
You will also need to add your dynamically created combobox to your listpanel or grid or whatever you are using. This works like this:
listpanelname.Children.Add(comboboxname);
Just add that to the "for" loop.

Right way to set selected text of combobox in winforms?

I have a form that takes in an object in it's constructor and populates controls on the form from properties in that object. I am having an issue where I can't set a ComboBox's SelectedText property, or at least it isn't working how I expect it to.
public Form(ValueHoldingObject obj)
{
// yeah I know this is not a very clean way to populate the combobox, the issue
// isn't limited to the combobox so I don't think this is relevant
List<int> items = Repo.GetAllItems().Reverse();
foreach (int id in checkInPrizeIds.Take(100))
// Insert at beginning to put more recently used items at the top
combobox.Items.Insert(0, id);
combobox.DropDownHeight = 200;
combobox.SelectedText = obj.StringProperty;
}
When I am testing this form the text of the combobox isn't being populated. If I add a breakpoint on the line where I assign the text it DOES get assigned, so some event is firing (multiple focus change events probably) and making it work the way I want. Obviously I can't use a breakpoint as a fix in production code. Am I assigning this value incorrectly? Should I be using a different method to populate the values?
Further testing has reviled that it isn't just the combobox, all of my controls are only being populated correctly if I have the breakpoint.
In the constructor, you need to set the selected item, for example:
foreach ( var item in combobox.Items )
if ( (string)item == obj.StringProperty )
combobox.SelectedItem = item;
Or:
foreach ( var item in combobox.Items )
if ( (int)item == Convert.ToInt32(obj.StringProperty) )
combobox.SelectedItem = item;
It's confusing but despite its name, the property SelectedText is not really the selected item... because combo box items are objects and not strings: texts shown are a representation of the item objects using ToString().
Therefore setting the selected text will not guarantee to select an item and we can prefer setting the SelectedItem.
In addition to these considerations, you set the selected text property in the constructor after populating the combo box and that can cause problems because it is before the form and the control are drawn or something like that... that is to say perhaps before the ToString() methods are called on items to prepare the visual cache, so setting the selected text can't get a match with the list.
Setting the selected text selects an existing item if done in the form load or shown events.
private void Form_Load(object sender, EventArgs e)
{
combobox.SelectedText = obj.StringProperty;
}
ComboBox.SelectedText doesn't give me the SelectedText
ComboBox.SelectedText Property

Multi value ListBox automatically selects undesired item

I have an object that has some attributes from the list selected - let's say a Promotion that can have 0 to X communication channels. To display/edit this information I am using a listbox with option SelectionMode==MultiExtended.
But in some cases it is behaving strangely
I have Promotion with 2 communication channels selected (first and last out of three channels),
I click on a second channel (that previously was the only unselected channel) and know it shows, that 1st and 2nd channels are selected (I placed a check at the beginning of the listbox SelectedIndexChanged event - and it shows that SelectedItems.Count==2, although I clicked on a single item not holding Ctrl or Shift keys) and in this case SelectedIndexChanged event is triggered twice in all other cases it is triggered just once
This happens only after the first time I open this dialogform, if I manually select 1st and 3rd item of Channels, and then click on the 2nd item - then it works properly
Screencast of a problem in action
http://screencast.com/t/lVs0e9oau
This is how I load list of all possible channels into listbox
foreach (var ct in Promotion_operations.Configuration.PromoCommunicationTypes)
{
KeyValuePair<string, PromotionCommunicationType> nct =
new KeyValuePair<string, PromotionCommunicationType>(ct.Name, ct);
communications.Add(nct);
}
PromotionCommunicationList.DataSource = communications; //Promotion_operations.Configuration.PromoCommunicationTypes;
PromotionCommunicationList.DisplayMember = "Key";
PromotionCommunicationList.ValueMember = "Value";
This is how I load selecteditems based on Promotion's data
private void LoadSelectedCommunicationsList(ListBox lstbox, List<PromotionCommunication> communications)
{
lstbox.SelectedItems.Clear();
foreach (var ct in communications)
{
for (int j = 0; j < lstbox.Items.Count; j++)
{
if (ct.CommunicationType.Id == ((KeyValuePair<string, PromotionCommunicationType>)lstbox.Items[j]).Value.Id)
{
lstbox.SelectedItems.Add(lstbox.Items[j]);
}
}
}
}
What could be the cause of this behaviour?
that clicking on one previously unselected list selects both - newly selected item and first item of the list?
Your PromotionCommunicationList and HistoryCommunicationList are sharing the same reference to your list of objects as DataSource. That said, they have the same BindingContext and share the same CurrencyManager. CurrencyManager is remembering selected items of your ListBox control and that's where your conflict is created because he's saving selected items of both of your ListBoxes. You already found the solution for your problem because new CurrencyManager is created when you set "different" list (the copy of your original one) as DataSource. Another possible solution would be the creation of new BindingContext for one of your ListBox controls.
You can try this out:
PromotionCommunicationList.DataSource = communications;
(..)
HistoryCommunicationList.BindingContext = new BindingContext(); // Add this
HistoryCommunicationList.DataSource = communications;
It should solve your problem. For more information about BindingContext check this link on MSDN.
I found the cause of the problem, though I don't really understand why it caused such a behaviour (if someone will answer that question, I will accept it as an answer to this question)
I had 2 listbox-es in my form and both of them where using the same collection as a Datasource, BUT!!! SelectedItems was selected using code (acctually it seems that in winforms it is not possible to databind listbox's selecteditems)
INITIALLY My code was:
PromotionCommunicationList.DataSource = communications;
(..)
HistoryCommunicationList.DataSource = communications;
Corrected version is:
PromotionCommunicationList.DataSource = communications.ToList();
(..)
HistoryCommunicationList.DataSource = communications.ToList();
I know that ToList() makes a copy, but I don't understand what's wrong with having the same collection as DataSource for list items of 2 listbox-es? Why does this have an impact on SelectedItems collection?

combobox item selected To be fixed

I had a databound combobox in my windows form I populate it by a function deptload() IN FORM LOAD
public void DeptcomboLoad()
{
DataTable dt = depttrans.getDeptName();
Cmb_Department.DataSource = dt;
Cmb_Department.DisplayMember = "DepartmentName"; //CHAR
Cmb_Department.ValueMember = "DepartmentPK"; //INT
}
Now when an employee of a department (say accounts DepartmentName="Accounts " , DepartmentPK=23 ) login I want the ComboBox text to be selected as "acounts "
and when I go to get the selected value of the ComboBox I should get 23
I tried
Cmb_Department.selectedtext="Accounts"
Cmb_Department.Text="Accounts"
but its not giving the selected value
Can anyone give a suggestion
Instead of trying to put a value INTO the combobox, try to GET the SelectedItem like this:
string txt= Cmb_Department.SelectedItem.Text
or just:
string txt= Cmb_Department.SelectedText
To change selected value of the combobox you can use
SelectedItem property or SelectedIndex.
Index must be exact number in your data sourse, and Item must be exact object from datasource
You can get it to select the right item by issuing something like this:
Cmb_Department.SelectedValue = 23;
Where 23 comes from some other variable, maybe on another object, maybe from a local variable, whatever works in your case.
Now, to get the selected value you can use this statement:
var val = Cmb_Department.SelectedValue;
To get the selected text (which would be the text associated with the value):
var text = ((DataRow)Cmb_Department.SelectedItem)["DepartmentName"];
The reason I'm prescribing the aforementioned is because the SelectedText property is volatile, and the Text property doesn't always work based on how the DropDownStyle is set.
However, some would probably argue to get the same as the aforementioned you could issue this statement:
var text = Cmb_Department.Text;

treeView_selectedItemChanged event handler

I have a wpf c# application that gets the name of household chores from a text file and then loads then into a several lists such as a list of nameOfChore, a list of ChorePriority, and then load the lists into the treeview, when i select one of the tasks/chores in the treeView I am trying to get it to load the list data for the given chore into text boxes on the right. I have a for loop checking if the treeView selected item is equal to any of the names of chores, and if it is, it then loads the text box. The problem is with the selectName variable it should be loaded with the chore name such as "Cut Grass" but instead it gets loaded with "System.Windows.Controls.TreeViewItem Header:Cut Grass Items.Count:4" how can i get selectName to just equal the header of the selected treeView item. Thanks.
for (int i = 0; i < name.Count; ++i) {
//string selectName = treeView1.SelectedItem.ToString(); I have tried this, and it gets the same value
string selectName = treeView1.SelectedValue.ToString();
if (selectName == name[i])
{
in treeView_selectedItemChanged event handler use following code works fine for me:
string selectName = ((TreeViewItem)(treeView1.SelectedItem)).Header.ToString();
hope that's what you needed!

Categories

Resources