1

Want to concatenate all the items that are selected in my ListBox (SelectedItems). The list box is using a class (RegionModel) as a datadource.

I have this going in foreach loop, but I'd like to put this into a single line, if possible. What I have doesn't break, but it doesn't print, just the class name that the item represents.

namespace ProLimb.Models
{
    public class RegionModel
    {
        public string Continent { get; set; }
        public string Country { get; set; }
    }

    //TRYING TO GET TO WORK
    Regions = string.Join("; ", lstRegions.SelectedItems.OfType<object>());
}

I figure I need to cast it, it doesn't seem to work.

The final output should look like: "North; East; South; West", but instead it comes out: ProLimb.Forms.RegionModel

Mong Zhu
  • 23,309
  • 10
  • 44
  • 76
Mikey
  • 15
  • 5
  • the casting is not the problem. You need to override the `ToString` method in your `class RegionModel` this will determine what you will see as the output. [this post](https://stackoverflow.com/a/33166948/5174469) might help – Mong Zhu Sep 02 '19 at 06:38
  • which of the properties is supposed to hold the information "North; East; South; West" ? `Continent` ? or `Country` ? – Mong Zhu Sep 02 '19 at 06:51
  • added an answer – Gabriel Llorico Sep 02 '19 at 07:11

4 Answers4

1

two answers can solve your problem stated by Mong Zhu and Ehsan Sajjad

all you need to show us is which property you want to contain/display Continent or Country

or my answer which is reflection if you dont want to overwrite your ToString()

PropertyYouWantToShow is either Continent or Country

Regions = string.Join("; ", lstRegions.SelectedItems.OfType<object>()
                .Select(c => c.GetType()
                              .GetProperty("PropertyYouWantToShow") //will get property
                              .GetValue(c))); //will get values listed on PropertyYouWantToShow

or you could cast it in your selectas per Richard Barker but still add OfType<object>

Regions = string.Join("; ", lstRegions.SelectedItems.OfType<object>()
                .Select(c => ((RegionModel)c).PropertyYouWantToShow)); // either Country or Continent

or you could directly cast it in your OfType

Regions = string.Join("; ", lstRegions.SelectedItems.OfType<RegionModel>()
                .Select(c => c.PropertyYouWantToShow));
Gabriel Llorico
  • 1,783
  • 1
  • 13
  • 23
0

You can override the ToString() method for your class and then just call it in a linq select:

public class RegionModel
{
    public string Continent { get; set; }
    public string Country { get; set; }

    public override String ToString()
    {
       return $"{Country},{Continent}";
    }
}

and then :

string.Join("; ", lstRegions.SelectedItems);

The above is just an example to show how ToString() can be used here but you might need to return either only Country or Continent as per your need.

Ehsan Sajjad
  • 61,834
  • 16
  • 105
  • 160
  • Problem being that now, anywhere you ambiguously convert RegionModel to a string, say for instance logs, you'll see the results of the to string. That is very likely is breaking change to the code. – Richard Barker Sep 02 '19 at 07:15
0

You probably want to Cast() your entities. As far as I understand, SelectedItems is not a generic collection but still implements IEnumerable. If you want to use LINQ on it, you have two options:

  • If you know for sure collection only has items of certain type, you have to use Cast<T>() on a collection to transform IEnumerable into IEnumerable<T>.
  • If you're not sure what type of items are present in the collection, and only want to deal with items of a particular type ignoring all the others, you need to use OfType<T>(), yielding IEnumerable<T> that only contains objects of the specified type.

Try this:

Regions = string.Join("; ", lstRegions.SelectedItems.Cast<RegionModel>().Select(x => x.Country));

This would also work:

Regions = string.Join("; ", lstRegions.SelectedItems.OfType<RegionModel>().Select(x => x.Country));

Whether the latter is more preferable in your scenario is up to your programming style, but I recommend the first version. That way if the collection contains items of unexpected type, you won't ignore it and fail fast, which is preferable.

pneuma
  • 917
  • 5
  • 10
0

This way:

namespace ProLimb.Models
{
    public class RegionModel
    {
        public string Continent { get; set; }
        public string Country { get; set; }
    }

    //TRYING TO GET TO WORK
    Regions = string.Join("; ", lstRegions.SelectedItems.OfType<RegionModel>().Select(x => x.Continent));
}

You were trying to concatenate your objects but they aren't string, so you have to ask for the property you need.

Marco Salerno
  • 5,131
  • 2
  • 12
  • 32