I am stuck on how to show items from a list in a picker.
I can use a for loop and add the items to the Picker, is there any other way ? I have to also use bound values from the list. All I get right now is the type and not the ID or Category name i need.
Image of what I see...
private async void GetCategories(string url)
{
//get json as a string
var result = await _clientHttp.GetStringAsync(url);
var json = JsonConvert.DeserializeObject<List<CategoryList>>(result);
List<CategoryList> tempList = new List<CategoryList>();
foreach (var items in json)
{
tempList.Add(new CategoryList{CatId = items.CatId,category = items.category});
}
;
PickerCategory.ItemsSource = tempList;
}
You must override your CategoryList.ToString() method to display the appropriate values:
class CategoryList{
public string category {get;set;}
public override string ToString(){
return category;
}
}
Related
I'm using PRISM6.
In my Model I have simple:
public ObservableCollection<Id> Ids { get; }
In ViewModel I would like to return those items in public ObservableCollection<string> Ids
How can I convert it to string? At this moment I have:
private ObservableCollection<string> _ids = new ObservableCollection<string>();
public ObservableCollection<string> Ids {
get {
_ids.Add("Empty");
foreach (var item in _Model.Ids) {
_ids.Add(item.ToString());
}
return _ids;
}
}
But it does not work when I update my collection in Model.
My old version without convert works fine. public ObservableCollection<Id> Ids => _Model.Ids; I need it in string because somehow I need to add "Empty" to combobox. If ther is any better solution for it please tell me :)
I'm sure there are much better solutions out there, but here's one method I particularly like:
public class MainViewModel
{
// Source Id collection
public ObservableCollection<Id> Ids { get; }
// Empty Id collection
public ObservableCollection<Id> Empty { get; } = new ObservableCollection<Id>();
// Composite (combination of Source + Empty collection)
// View should bind to this instead of Ids
public CompositeCollection ViewIds { get; }
// Constructor
public MainViewModel(ObservableCollection<Id> ids)
{
ViewIds = new CompositeCollection();
ViewIds.Add(new CollectionContainer {Collection = Empty });
ViewIds.Add(new CollectionContainer {Collection = Ids = ids });
// Whenever something changes in Ids, Update the collections
CollectionChangedEventManager.AddHandler(Ids, delegate { UpdateEmptyCollection(); });
UpdateEmptyCollection(); // First time
}
private void UpdateEmptyCollection()
{
// If the source collection is empty, push an "Empty" id into the Empty colleciton
if (Ids.Count == 0)
Empty.Add(new Id("Empty"));
// Otherwise (has Ids), clear the Empty collection
else
Empty.Clear();
}
}
I'm trying to get the Tag associated to a value of ComboBox like this way:
var league = ((ComboBoxItem)this.League.SelectedValue).Tag.ToString();
Console.WriteLine(league);
The compiler show me a Invalid Cast Exception
I only want to get the associated Tag of the selected value by user, in particular:
(combobox value and Tag)
-Italy (item) - 10 (Tag)
-France (item) - 12 (Tag)
If the user select Italy, in the code I must get "10". But I can't do this, what am I doing wrong?
UPDATE (Populate combo):
List<RootObject> obj = JsonConvert.DeserializeObject<List<RootObject>>(responseText);
foreach (var item in obj)
{
foreach (var code in nation_code)
{
if (code.Equals(item.League))
{
League.Items.Add(item.Caption);
//link for each team
League.Tag = item.Links.Teams.href;
}
}
}
If you see the Tag is setting for the combo box itself and not for its individual item.
You can build a dictionary and use it as datasource of your combo box. Specify the value and display members of the combo box with dictionary key and value attributes
Try modifying the combo population logic as follows -
List<RootObject> obj = JsonConvert.DeserializeObject<List<RootObject>>(responseText);
Dictionary<string, string> comboSource = new Dictionary<string, string>();
foreach (var item in obj)
{
foreach (var code in nation_code)
{
if (code.Equals(item.League))
{
comboSource.Add(item.Caption, item.Links.Teams.href);
}
}
}
League.ValueMember = "Value";
League.DisplayMember = "Key";
League.DataSource = comboSource;
And then the required values can be fetched using the selectedText and selectedvalue properties.
League.SelectedText; //Return the "item.Caption"
League.SelectedValue; //Return the "item.Links.Teams.href"
For WPF we need to use different properties viz. ItemsSource,
DisplayMemberPath and SelectedValuePath while binding the combo
box. The above solution is for win forms.
You can add any type of object to a ComboBox, it does not need to be a string, it just needs to overwrite .ToString().
You could define a class:
class League {
public string Country { get; set; }
public int Id { get; set; }
public override string ToString() {
return Country;
}
}
and then just add these objects to the ComboBox:
comboBox.Items.Add(new League { Country = "France", Id = 10 });
You can then just cast the SelectedItem of your comboBox back to your class:
var selectedLeague = (League)comboBox.SelectedItem;
//access selectedLeague.Country;
//access selectedLeague.Id;
I have in a SearchFlyClass an Arraylist GetFly()
...
public ArrayList GetFly(int tip, string country)
{
...
var list = new ArrayList();
var reader = command.ExecuteReader();
if (reader.HasRows)
{
...
while (reader.Read())
{
decimal nr_zbor = reader.GetDecimal(cod_zbor);
string aeroport = reader.GetString(nume_aeroport);
string companie = reader.GetString(nume_companie);
list.Add(nr_zbor);
list.Add(companie);
list.Add(aeroport);
}
}
...
and I wish to put in Form1.cs the list in listview by columns[zbor(colZbor),airport(colAirport),company(colCompany)], but I don't now how
private SearchFlyClass searchFly = new SearchFlyClass();
private ArrayList fly = new ArrayList();
...
private void ShowResultFlySearch(int direction, string country)
{
fly = searchFly.GetFly(direction, country);
for (int count = 0; count < fly.Count; count++)
{
string zbor = fly[0].ToString();
string companie = fly[1].ToString();
string aeroport = fly[2].ToString();
ListViewItem searchlist = new ListViewItem();
searchlist.Items.Add(new ListViewItem(elem));
}
}
can someone help me, please?
First you have to put ListView to View mode details, which you do with following code (it is also possible with setting View property in designer):
ListView listView = new ListView();
listView.View = View.Details;
Then you have to assign columns to the listView (can also be done in designer):
listView.Columns.Add("zbor");
listView.Columns.Add("airport");
listView.Columns.Add("company");
After this you have to assign other columns to ListViewItem subitems, by modifying your function:
private void ShowResultFlySearch(int direction, string country)
{
fly = searchFly.GetFly(direction, country);
for (int count = 0; count < fly.Count; count++)
{
string zbor = fly[0].ToString();
string companie = fly[1].ToString();
string aeroport = fly[2].ToString();
ListViewItem listViewItem = new ListViewItem(zbor);
listViewItem.SubItems.Add(airport);
listViewItem.SubItems.Add(companie);
listView.Items.Add (listViewItem);
}
}
The function assumes that it is in Form1.cs and that you have listView variable instantized as class variable of type ListView. Basics of C# and object oriented programming.
There are lots of issues with this code. Firstly, is there any reason that you're using ArrayList instead of the generic collection types? E.g. List<T>
Secondly, I would create a type to store all of the related data for one instance of your entity, rather than putting the column values for the entity into an untyped collection.
Thirdly, your aren't referencing count anywhere in your for loop - presumably because the query is returning a single entity, and therefore the for loop is redundant because you know the number of items returned for a single entity. You are also using a variable elem which doesn't seem to have been defined.
Updated
Define a type that describes your entity:
public class Flight
{
public decimal Code { get; set; }
public string Company { get; set; }
public string Airport { get; set; }
}
Change your method to return an instance of your entity:
public Flight GetFlight(int tip, string country)
Create a new instance to return from the method and populate it from your database query result:
var flight = new Flight();
flight.Code = reader.GetDecimal(cod_zbor);
flight.Airport = reader.GetString(nume_aeroport);
flight.Company = reader.GetString(nume_companie);
return flight;
Now your other method can use the updated method:
var flight = searchFly.GetFlight(...);
// access flight properties here
This assumes that your query returns a single entity. If it returns a collection, then you can use List<Flight> or IEnumerable<Flight> as your return type as appropriate.
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.
I am abit new in C# and i am trying to insert an object to a CheckedListBox,
so this inserted item will have a title inside the checked list (my object contains a string field inside it which I want to be displayed in the CheckedListBox).
for example this is my class:
public class InfoLayer
{
private string LayerName;
private List<GeoInfo> GeoInfos;
public InfoLayer()
{
LayerName = "New Empty Layer";
GeoInfos = new List<GeoInfo>();
}
public InfoLayer(string LayerName)
{
this.LayerName = LayerName;
GeoInfos = new List<GeoInfo>();
}
public InfoLayer(string LayerName,List<GeoInfo> GeoInfosToClone):this(LayerName)
{
foreach (GeoInfo item in GeoInfosToClone)
{
GeoInfos.Add((GeoInfo)((ICloneable)item).Clone());
}
}
public GeoInfo SearchElement(long id)
{
foreach (GeoInfo info in GeoInfos) // foreach loop running on the list
{
if (info.INFOID == id)
return info; // return the item if we found it
}
return null;
}
public GeoInfo SearchElement(string name)
{
foreach (GeoInfo info in GeoInfos)
{
if (info.INFONAME.CompareTo(name)==0)
return info;
}
return null;
}
public override string ToString()
{
string toReturn = "";
for (int i = 0; i < GeoInfos.Count; i++) // for loop running on the list
{
toReturn += String.Format("{0}\n",GeoInfos[i].ToString()); // piping another geoinfo
}
return toReturn;
}
public string LAYERNAME{get{return LayerName;}}
my class also contains a tostring overrider inside her (not what i want to display)
thanks in advance for your help.
Override ToString() in your class, the class that the object is an instance of.
Edit:
You don't want to display the contents of ToString(). You want to display the LayerName, don't you? Perhaps you should display the values with Databinding instead. Then you can set DisplayMember to your new LAYERNAME property.
I believe this is what you are trying to achieve:
checkedListBox1.Items.Add(yourObject.stringField);
((MyObjectType)checkedListBox1.Items(index)).Name = "whatever"
You will have to know the index of the object you want to change.
You'll just have to override the ToString method in your class so that it returns this Name property value.
public overrides string ToString() {
return Name;
}
It will then display its name when added to your CheckedListbox.