views:

205

answers:

2

I have a list box that contains a list of WorkItems (from TFS). I want to add items to be selected, but it is failing to identify the items as the same.

Here is my code

    public void SelectQueryResultItem(WorkItem item)
    {
        lstQueryResults.SelectedItems.Add(item);
    }

This works great when the WorkItem passed in is from the same query that is in the SelectedItems list. However if it came from a different query (ie the object reference is not the same) then it does not identify the object correctly.

I assume it is comparing on reference. I want to override that and make it compare on item.Id. Is there a way to do that?

Note that I am using the WPF ListBox, not the WinForms ListBox

+1  A: 

Rather than inherit from ListBox, have you tried overriding Equals on the WorkItem class to do a comparison by ID? It's not ideal since obviously two instances with the same ID are not necessarily equal. But I'm not sure how you might coax the Selector base class into using a custom IComparer.

EDIT I dug in a little deeper and found that you can derive from CollectionView (which is a wrapper around a collection to be bound in WPF) and override its Comparer property to return a custom IComparer. So you could create something like a WorkItemCollectionView that overrides Comparer and return something like a WorkItemIDComparer.

Hope this helps.

Josh Einstein
Alas WorkItem is a sealed class... I don't know anyway around that. (An extension method will take the existing method if it is already there)
Vaccano
A: 

Here is a non-cool way to solve this issue.

    public void SelectQueryResultItem(WorkItem item)
    {
        // Because the ListBox only compares by reference, 
        //  we need to find the matching WorkItem (if any)
        //  before adding it to the selected list.
        WorkItem matchingWorkItemInList = GetWorkItemInQueryResultByID(item.Id);
        if (matchingWorkItemInList != null)
            lstQueryResults.SelectedItems.Add(matchingWorkItemInList);
    }

    public WorkItem GetWorkItemInQueryResultListByID(int Id)
    {
        foreach (WorkItem workItem in lstQueryResults.Items)
        {
            if (workItem.Id == Id)
            {
                return workItem;
            }
        }
        return null;
    }

Basically I am circumventing the compare system in the ListBox.

It would be nice if WPF allowed me to have access to the comparer so I can compare by value if I want to and not need to do this.

Vaccano
Did you see my edit, it appears that this comparer logic is done by CollectionView, not the Selector/ListBox. To override the behavior you need to provide your own CollectionView.
Josh Einstein