5

I got 3 listViews 2 textbox and 2 buttons in WinForm.

Program Description: The program adds numbers to the listview by typing in numbers in the textbox and clicking the add button

Goal: I want to be able to use the IEnumerable.Except method to output only the unique numbers in listView3, for example in the picture below the unique numbers are 3 and 7 in listView1 and listView2. ListViewItem lvi = new ListViewItem(textBox1.Text); listView1.Items.Add(lvi);

ListViewItem lv = new ListViewItem(textBox2.Text);
listView2.Items.Add(lv);

//im doing somthing wrong here...
var nonintersect = listView1.Except(listView2).Union(listView2.Except(listView1));

//populate listview3 with the unique numbers...
// foreach (item )
// {

// }

Error Message: System.Windows.Forms.ListView' does not contain a definition for 'Except' and no extension method 'Except' accepting a first argument of type 'System.Windows.Forms.ListView' could be found (are you missing a using directive or an assembly reference?)

enter image description here

taji01
  • 2,527
  • 8
  • 36
  • 80
  • 1
    How about using the .Distinct extension method. – Mr. B Aug 13 '15 at 22:39
  • Please read [this](https://blog.mariusschulz.com/2011/08/08/why-enumerableexcept-might-not-work-the-way-you-might-expect) famous blog to understand the internals of `Enumerable.Except()` method. – RBT May 03 '18 at 04:57

4 Answers4

5

It's called Symmetric DIfference and it's simple as that.

var nonintersect = listView1.Except(listView2).Union(listView2.Except(listView1));

Source Origin

Community
  • 1
  • 1
Orel Eraki
  • 11,940
  • 3
  • 28
  • 36
  • Clever. I hand't though of an approach with `Union` yet. – BradleyDotNET Aug 13 '15 at 22:45
  • How would i add this to my code? Can you provide the full code with array1 please. I'm still knew @OrelEraki – taji01 Aug 13 '15 at 22:45
  • @BradleyDotNET, Thanks, but it's Øyvind Bråthen answer, find it long time ago when i thought if there will be a nicer way of doing it. – Orel Eraki Aug 13 '15 at 22:45
  • When i copied and pasted it it gives me an error here: listView1.Except(listView2) and (listView2.Except(listView1)); @OrelEraki – taji01 Aug 13 '15 at 22:50
  • 2
    @taji01 You need to be a lot more specific. You can't just post his line and say there is an error! Also, you need to be able to apply a concept in an answer to your code. We are here to provide answers, not do your work for you. – BradleyDotNET Aug 13 '15 at 22:52
  • I'm sorry but i did try the problem myself for a couple of days now. I was trying to be clear, i only posted the lines where the red lines occurred. I'm still new to programming, but ill try to apply the concept. @BradleyDotNET – taji01 Aug 13 '15 at 23:02
  • @taji01 Ok, but you didn't say what the error *was*, and there was only one line to start with, so pointing it seemed a bit... silly. – BradleyDotNET Aug 13 '15 at 23:04
  • Sorry this was the Error: System.Windows.FormListView does not contain a definition for 'Except' and no extension method 'Except' System.Windows.FormListView could be found (are you miss missing a using directive or an assembly reference?) @BradleyDotNET – taji01 Aug 13 '15 at 23:11
  • @taji01 Ah, yes. You need to get the actual collection the list view holds (ie `Items`) and use that, not the listview itself (which is not an `IEnumerable`) – BradleyDotNET Aug 13 '15 at 23:15
  • @BradleyDotNET, I really don't know if i should write the lousy for loop that will populate the results he wants, or just letting him struggling it with himself. After all were not Code Factory. – Orel Eraki Aug 13 '15 at 23:16
  • @OrelEraki I think you answered the question. The title is even about `IEnumerable` (not `ListView`). The question of "How to turn this ListView into an `IEnumerable` of its contents is seperate (though trivial, just use `Select` or your for loop). – BradleyDotNET Aug 13 '15 at 23:18
  • I would appreciate it if you did. I've been stuck trying to figure this out for a couple of days now and my last option was asking for help. @BradleyDotNET – taji01 Aug 13 '15 at 23:19
  • @taji01 Considering there are now *two* hints on how to do this above, perhaps you should give it a go first? Do some Googling? Ask a seperate question when all that fails? – BradleyDotNET Aug 13 '15 at 23:20
  • I'll keep trying. Hopefully ill get it by today, thanks for the hints guys. I appreciate it. @OrelEraki – taji01 Aug 13 '15 at 23:25
1

You can't do this with just Except, as it would only return { 3 } or just { 7 } in your example. However, if you take the set intersection between the two { 1, 2, 4 } and then use Except, you can get the de-intersection (which is basically what you are looking for):

IEnumerable<int> allObjects = list1.Concat(list2);
IEnumerable<int> intersection = list1.Intersect(list2);
IEnumerable<int> deIntersection = allObjects.Except(intersection);
BradleyDotNET
  • 60,462
  • 10
  • 96
  • 117
  • No need to do the `.Distinct()` the way `Execpt` processes it performs a distinct on the input list as it goes. The documentation specifically says it is the "Set Difference" so you can rely on this behavior. – Scott Chamberlain Aug 13 '15 at 22:46
  • @ScottChamberlain Thanks for the note, I'll keep that in mind (and fixed the code). – BradleyDotNET Aug 13 '15 at 22:53
0

You would need to do something like this:

IEnumerable<string> common =
        Enumerable
            .Intersect(
                listView1.Items.Cast<ListViewItem>().Select(x => x.Text),
                listView2.Items.Cast<ListViewItem>().Select(x => x.Text));

IEnumerable<string> all =
        Enumerable
            .Union(
                listView1.Items.Cast<ListViewItem>().Select(x => x.Text),
                listView2.Items.Cast<ListViewItem>().Select(x => x.Text));

IEnumerable<string> unique = all.Except(common);
Enigmativity
  • 113,464
  • 11
  • 89
  • 172
0

Except is not defined for ListView. It's actually an extension method that is defined in System.Linq.Enumerable. You're probably confused because you can call Except from IList<T> (since IList<T> derives from IEnumerable<T>), but what you're trying to do will never work because ListView doesn't inherit from IEnumerable<T>. The exception you're getting is the correct behavior.

To get the Except behavior for your controls, you'll need to manipulate the underlying collection and then bind the resulting collection object to the ListView control.

smartcaveman
  • 41,281
  • 29
  • 127
  • 212