Using listbox, how to find that exact object? - c#

I think this is a somewhat easy answer but Im not able to understand how to do it.
I have an object (lets call it A) with a list of other objects (for example places)
So Im creating a Webapp and in that page I have a listbox of places (Im using the name of the places (string) as a unique id). The question is when I select an item from that list, how do I find that item in the list of places?
for example:
page.aspx:
<p style="margin-left: 40px">
Select place:</p>
<p style="margin-left: 40px">
<asp:ListBox ID="listplace" runat="server"></asp:ListBox>
</p>
page.aspx.cs:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
listplace.DataSource = A.listOfPlaces;
listplace.DataBind();
}
}

Hopefully this can help you:
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Windows.Forms;
namespace ListBox_42581647
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Doit();
}
private void Doit()
{
ListBox lb = new ListBox();//create a listbox
lb.Items.Add(new aPlace { placename = "TheBar", placeCoolFactor = "booze" });//add something to the listbox
lb.Items.Add(new aPlace { placename = "TheHouse", placeCoolFactor = "bowl"});//add something to the listbox
lb.Items.Add(new aPlace { placename = "ThePark", placeCoolFactor = "dogs" });//add something to the listbox
lb.SelectedItem = lb.Items[1];//lets fake a selection
var theSelectedPlace = lb.SelectedItem;//the actual item selected
var theSelectedPlaceName = ((aPlace)lb.SelectedItem).placename;//the selected item place name
var theSelectedPlaceCoolFactor = ((aPlace)lb.SelectedItem).placeCoolFactor;//the selected item place cool factor
//now I'll create your (lets call it A)
List<aPlace> parallelList = new List<aPlace>();//lets call it A
parallelList.Add((aPlace)lb.Items[0]);//This list contains the same items your ListBox contains
parallelList.Add((aPlace)lb.Items[1]);//This list contains the same items your ListBox contains
parallelList.Add((aPlace)lb.Items[2]);//This list contains the same items your ListBox contains
//find the selected by matching the selected Placename
aPlace theChosenPlace = parallelList.Where(p => p.placename == theSelectedPlaceName).FirstOrDefault();
//find the selected by matching the actual item
aPlace theChosenPlace2 = parallelList.Where(p => p == theSelectedPlace).FirstOrDefault();
}
}
public class aPlace
{
public string placename { get; set; }
public string placeCoolFactor { get; set; }
}
}

You can try:
string currPlace = listplace.SelectedItem.ToString();
string place = A.listOfPlaces.Where
(x => x.Contains(currPlace)).FirstOrDefault();

Related

Selecting TextCell by code doesn't highlight row

When I click a TextCell in a ListView, the row is highlighted.
However, when I programatically select a row / a TextCell, the row isn't highlighted.
Therefore it isn't possible to indicate to the user which value in a ListView is currently selected unless he changes the selection by tapping a row.
Is that a bug or a missing feature, or how could I achieve the highlighting via code?
Sample code is attached below.
using MyApp.Model;
using System.Collections.Generic;
using Xamarin.Forms;
namespace MyApp
{
public class IntSelector : ContentPage
{
private ListView m_ListView;
public IntSelector(int uSelectedInt)
{
DataTemplate nTemplate = new DataTemplate(typeof(TextCell));
// We can set data bindings to our supplied objects.
nTemplate.SetBinding(TextCell.TextProperty, "String");
nTemplate.SetBinding(TextCell.DetailProperty, "Int");
List<clsStringInt> nList = new List<clsStringInt>();
clsStringInt nItem1 = new clsStringInt { String = "German", Int = 1031 };
clsStringInt nItem2 = new clsStringInt { String = "English", Int = 1033 };
clsStringInt nItem3 = new clsStringInt { String = "Spanish", Int = 1034 };
nList.Add(nItem1);
nList.Add(nItem2);
nList.Add(nItem3);
m_ListView = new ListView();
m_ListView.ItemTemplate = nTemplate;
m_ListView.ItemsSource = nList;
m_ListView.ItemSelected += this.OnSelection;
m_ListView.SelectedItem = nItem2;//this triggers the "OnSelection" event, so it works
nItem2.String = "->> " + nItem2.String; //the item's new string is display in the ListView, so that works as well
//what DOESN'T work is the highliting
this.Content = m_ListView;
}
void OnSelection(object sender, SelectedItemChangedEventArgs e)
{
if (e.SelectedItem == null)
{
return; //ItemSelected is called on deselection, which results in SelectedItem being set to null
}
clsStringInt n = (clsStringInt)e.SelectedItem;
string sSelectedIntAsString = n.Int.ToString();
DisplayAlert("Item Selected", sSelectedIntAsString, "Ok");
}
}
}
namespace MyApp.Model
{
public class clsStringInt
{
public string String { get; set; }
public int Int { get; set; }
}
}
As mentioned in the comments you are testing on a UWP Forms app which this appears to be a bug specifically on that platform seeing how it works fine on Android and iOS.
I was able to work around this by setting the selected item in OnAppearing instead of in the Page constructor to get it to highlight.

Populate Combobox from a list

Newb here,
I'm currently working on a form which has a combo box, which will show several Charlie Brown TV specials which you can click on to select and see a description of, rating, runtime, etc. I'm close but I'm not there in terms of populating the combo box and i'm hoping for some help and guidance. I have looked at several things others have done but i'm not knowledgeable enough to deduce the answers from what i've been able to see so far.
Right now i'm trying too:
1. get the listings from your load method
2. loop through them
3. Access my combo box to populate the box with the times from the listing.
Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Globalization;//Used for Sting.ToUpperCase...
using System.Threading;
using System.Threading.Tasks;// Needed for Streaming...
using System.IO;// Needed for Streaming...
namespace a100___GUI___VideoStoreSelections
{
public partial class FormMovieLookUp : Form
{
private const String FILE_NAME = "txt_movieDescriptions.txt";//connect to text file in debug
private List<Listing> films { get; set; }
public FormMovieLookUp()
{
InitializeComponent();
}
private void cmbMovieListingBox_SelectedIndexChanged(object sender, EventArgs e)
{
txtTitleBox.Text = cmbMovieListingBox.SelectedItem.ToString();
}
//ToolBox -- my program specific tools
public List<Listing> LoadListings()//load movie descriptions as list
{
StreamReader fileIn = new StreamReader(FILE_NAME);
List<Listing> entries = new List<Listing>();
//loop through every line of the file
while (!fileIn.EndOfStream)
{
String line = fileIn.ReadLine();
String[] pieces = line.Split(':');
if (pieces.Length < 4) continue;//error handling - set to length of text items
Listing myListing = new Listing(pieces[0], pieces[1], pieces[2], pieces[3]);
entries.Add(myListing);
}
fileIn.Close();
return entries;
}
private void FormMovieLookUp_Load_1(object sender, EventArgs e)
{
films = LoadListings();
foreach (Listing film in films)
{
Console.WriteLine(film);
cmbMovieListingBox.Items.Add(film.GetFilmTitle());
}
}
}
}
Listing.CS
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace a100___GUI___VideoStoreSelections
{
public class Listing
{
private String filmTitle;
private String description;
private String filmRunTime;
private String filmRating;
public Listing(String filmTitle, String description, String filmRunTime, String filmRating)
{
this.filmTitle = filmTitle;
this.description = description;
this.filmRunTime = filmRunTime;
this.filmRating = filmRating;
}
public String GetFilmTitle() { return filmTitle; }
public String GetDescription() { return description; }
public String GetFilmRunTime() { return filmRunTime; }
public String GetFilmRating() { return filmRating; }
}
}
So this is what i'm trying to do to populate my combo box. Any help is thankfully received.
I would hold List<Listing> at the class level so you can access it when a user clicks on it. I would also throw this on it's own thread and not directly in the Load event. If it's a long process you will hang the ui.
private List<Listing> films { get; set; }
Load
films = LoadListings();
foreach (Listing film in films)
{
cmbMovieListingBox.Items.Add(film.GetFilmTitle());
}
When the user selects the item
Listing film = films.Where(f => f.GetFilmTitle().Equals(cmbMovieListingBox.SelectedValue)).FistOrDefault();
if (film != null)
{
//do work
}
if you are asking what i think you are asking, you need something like this in your form load:
foreach(Listing listing in LoadListings()){
cmbMovieListingBox.Items.Add(listing.GetFilmTitle());
}
Remove the {get; set;} from the list declaration. It's not needed there.
Define your class like this:
public class Listing
{
private String filmTitle {get; set;}
private String description {get; set;};
…
}
On the form load event set the ComboBox DisplayMember and ValueMember to "filmTitle"
cmbMovieListingBox.DisplayMember = "filmTitle";
cmbMovieListingBox.ValueMember = "filmTitle"
Finally, you must set the DataSource of the ComboBox to the list
cmbMovieListingBox.DataSource = films;
And there you have it. The rest of your code should function now.
There's one issue with visual controls updating (such as ComboBox etc): you'd rather prevent them from re-painting at each data change (at each item addition in your case):
cmbMovieListingBox.BeginUpdate(); // <- Stop painting
try {
// Adding new items into the cmbMovieListingBox
foreach(var item in LoadListings())
cmbMovieListingBox.Items.Add(item.GetFilmTitle());
finally {
cmbMovieListingBox.EndUpdate(); // <- Finally, repaint if required
}
A line of the code of Tsukasa doesn't work because it is written FistOrDefault() instead of FirstOrDefault()
Listing film = films.Where(f => f.GetFilmTitle().Equals(cmbMovieListingBox.SelectedValue)).**First**OrDefault();
Sorry I don't have enough point to just add a comment...
Maybe it will help somebody. But in my situation I had to use cmbMovieListingBox.Text instead of cmbMovieListingBox.SelectedValue (like #Tsukasa example):
Listing film = films.Where(f => f.GetFilmTitle().Equals(cmbMovieListingBox.Text)).FirstOrDefault();
if (film != null)
{
//do work
}
And also FirstOrDefault() instead of FistOrDefault().
Hope it helps to someone
that what i did to my Code
int Count;
foreach(String i in Languages)
{
LangComboBox.Items.Add(Languages[Count]);
Count++;
}

Refreshing the listbox item after an element is changed

I have a ParameterItem class for adding some items to a listbox:
class ParameterItem
{
public string Name { get; set; }
public string Value { get; set; }
public ParameterItem(string name, string value)
{
Name = name;
Value = value;
}
public override string ToString()
{
return Name + " = " + Value;
}
public override bool Equals(object obj)
{
if (obj is ParameterItem)
return (Name == ((ParameterItem)obj).Name);
return false;
}
public override int GetHashCode()
{
return Name.ToLowerInvariant().GetHashCode();
}
}
And you can add items to the listbox using two textboxes (name and value). When you click on an item in the listbox, the textboxes get filled with the name and the value of the ParameterItem. I have the following code to change the contents of the selected ParameterItem in the listbox:
private void btnSaveParameter_Click(object sender, EventArgs e)
{
ParameterItem currentParameter = new ParameterItem(textParameterName.Text,
textParameterValue.Text);
// If we already have the parameter set then edit it.
if (lstbxSetParameters.Items.Contains(currentParameter))
{
((ParameterItem)lstbxSetParameters.SelectedItem).Value = currentParameter.Value;
lstbxSetParameters.;
}
// If it's not set yet then add it to the listbox.
else
{
lstbxSetParameters.Items.Add(currentParameter);
textParameterName.Text = String.Empty;
textParameterValue.Text = String.Empty;
}
}
The problem is, even though I can change the contents of the selected ParameterItem, in the listbox, it still looks like it is not changed.
For example I have a parameter in the list box:
TestParameter = 10
And I change the ParameterItem to
TestParameter = 5
but in the listbox it still looks like
TestParameter = 10
even though it's been changed.
How can I solve this problem? I think the listbox item should call the ToString() method of the ParameterItem again and refresh itself but how?
Or is there a better way to add key value pairs in the listbox?
You can change the selected item by remove it and insert it again.
// If we already have the parameter set then edit it.
if (lstbxSetParameters.Items.Contains(currentParameter))
{
var newItem = new ParameterItem((lstbxSetParameters.SelectedItem as ParameterItem).Name, currentParameter.Value);
var index = lstbxSetParameters.SelectedIndex;
lstbxSetParameters.Items.RemoveAt(index);
lstbxSetParameters.Items.Insert(index, newItem);
lstbxSetParameters.SelectedIndex = index;
}
My solution:
string[] nList = new string[lb.Items.Count];
nList = lb.Items.OfType<string>().ToArray();
nList[lb.SelectedIndex] = newValue;
lb.Items.Clear();
lb.Items.AddRange(nList);
This way instead of changing the selected item (with a lot of problem) I reloaded the Listbox with the item changed in the array.

Problem in binding a listbox to data

I have a table that have these fields: ID , Name
I have bound a listbox to the table.
My question is, when the user has selected an item in listbox, how would I find out what the ID of the selected item is?
Note: The id is not equal to the selectedindex or id of items in items list
e.g.
Suppose you have a DataTable dt, with columns ID and Name in it.
then while binding include the following code,
this.listbox.DataSource = dt;
this.listbox.DisplayMember = "Name";
this.listbox.ValueMember = "ID";
while reading the selected values of listbox,
this.listbox.SelectedItem will give u the selected Name and
this.listbox.SelectedValue will give u the corresponding ID
test it
lst.SelectedItem.Value;
OR
lst.SelectedValue;
where lst is a ListBox Cotrol
What type of application is this? ASP.net, Windows Forms, WPF?
I have a feeling you are working with Windows Forms, as the other two are much clearer...
Here is some code for a Windows Forms App... Basically, you create your own class, and use that for the list items. The list box will display the results of the ToString() method, so override that to get the value you wanna display. When you access ListBox.SelectedItem, it will be an instance of the class you defined, and you can access whatever properties are necessary:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
MyListItem item1 = new MyListItem("Java", 1);
MyListItem item2 = new MyListItem("C#", 221);
MyListItem item3 = new MyListItem("C++", 13);
listBox1.Items.Add(item1);
listBox1.Items.Add(item2);
listBox1.Items.Add(item3);
}
private class MyListItem
{
public string ItemName { get; set; }
public int ItemId { get; set; }
public MyListItem(string name, int id)
{
this.ItemName = name;
this.ItemId = id;
}
public override string ToString()
{
return this.ItemName;
}
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
MyListItem selectedItem = (MyListItem)listBox1.SelectedItem;
MessageBox.Show(string.Format("Name is: {0}, Id is: {1}", selectedItem.ItemName, selectedItem.ItemId));
}
}

Make ListBox items have a different value than item text

I want a ListBox full of items. Although, each item should have a different value.
So when the user selects an item and presses a button, a method will be called which will use the value the select item has.
I don't want to reveal the item values to the user.
EDIT: This is not for ASP.NET, it's for a Windows Forms application. I just thought the HTML example would be easy to read.
I have the inspiration from HTML:
<form>
<input type="radio" name="sex" value="Value1" /> Male
<br />
<input type="radio" name="sex" value="Value2" /> Female
</form>
This also allows me to use different values than what the user sees.
You can choose what do display using the DisplayMember of the ListBox.
List<SomeData> data = new List<SomeData>();
data.Add(new SomeData() { Value = 1, Text= "Some Text"});
data.Add(new SomeData() { Value = 2, Text = "Some Other Text"});
listBox1.DisplayMember = "Text";
listBox1.DataSource = data;
When the user selects an item, you can read the value (or any other property) from the selected object:
int value = (listBox1.SelectedItem as SomeData).Value;
Update: note that DisplayMember works only with properties, not with fields, so you need to alter your class a bit:
public class SomeData
{
public string Value { get; set; };
public string Text { get; set; };
}
items have a property called 'Tag', which you can use to store any information you want (hidden from the user)
ListViewItem myItem = new ListViewItem();
myItem.Text = "Users see this";
myItem.Tag = "Users don't see this";
(or set the appropriate properties in the property explorer)
Very simple:
foreach(var item in *Your Source List*)
{
ListItem dataItem = new ListItem();
dataItem.Text = "value to show";
dataItem.Value = *another value you want*;
listBox.Items.Add(dataItem);
}
As stated by the 1st answer, the use of DisplayMember works whether you are using asp.net or winforms.
And to comment a bit more, it also works if you are using the rather old fashion Items.add way of adding items to a ListBox.
Just for fun, here is a simple demo of what you need (just create a new form and drop on it a ListBox and a Label):
public partial class Form1 : Form
{
class Customer
{
public string FirstName { get; set; }
public string LastName { get; set; }
public override string ToString()
{
return string.Format("{0} {1}", LastName, FirstName);
}
}
public Form1() { InitializeComponent(); }
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
listBox1.DisplayMember = "LastName";
listBox1.DataSource = GetCustomers();
//listBox1.Items.AddRange(GetCustomers().ToArray());
}
private IEnumerable<Customer> GetCustomers()
{
return new List<Customer>()
{
new Customer() { FirstName = "Gustav", LastName = "MAHLER" },
new Customer() { FirstName = "Johann Sebastian", LastName = "BACH" }
};
}
private void lb_SelectedIndexChanged(object sender, EventArgs e)
{
label1.Text = listBox1.SelectedItem.ToString();
}
}
Enjoy
PS: #2nd post Tag is not available to ListBox: because it accepts an array of object, not a specific item container like ListView... but you don't need any in your case. Tag is useful when you want to carry additional data along with a specific TreeViewItem or ListViewItem for example.
By the way, Tag is defined at the Control level and so exists for Button, Label, and so on... but for my part I think it is rather a bad idea to store business data in it (untyped, UI coupled...) apart from the ListView and TreeView cases for which it is rather convenient.
Easy!
protected void Page_Load(object sender, EventArgs e)
{
llenaListBox(ListBox1, 0, 10);
}
private void llenaListBox(ListBox PoListBox, int PiMinimo, int PiMaximo)
{
int Li;
for (Li = PiMinimo; Li <= PiMaximo; Li++)
{
ListItem obj = new ListItem();
obj.Text = Li.ToString();
obj.Value = Li.ToString();
PoListBox.Items.Add(obj);
}
}

Categories