A reusable Previous/Next Contact Collection ViewModel class I often use a ViewModel class that contains a collection of Contacts and allows me to iterated through the collection with Previous and Next buttons.

I find that I've got duplicate versions of this class all over the place and I'd like to make my code reusable.

How would I go about making the following code reusable (i've been going round in circles for a while now):

public class PartiesViewModel : BaseViewModel
{
    const int MaxParties = 20;

    public ObservableCollection&lt;Party&gt; Parties { get; set; }

    public PartiesViewModel(ObservableCollection&lt;Party&gt; parties)
    {
        Parties = parties;
        Party = Parties.FirstOrCreateIfEmpty();

        Party.PropertyChanged += UpdatePartyShortNamesList;
        Parties.CollectionChanged += Parties_CollectionChanged;

        ClearCommand = new RelayCommand(ClearPressed, CanClear);
        NextCommand = new RelayCommand(NextPressed, CanPressNext);
        PrevCommand = new RelayCommand(PrevPressed, CanPressPrev);
    }

    void UpdatePartyShortNamesList(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (e.PropertyName == "ShortName")
            NotifyPropertyChanged("PartyShortNames");
    }
    void Parties_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        NotifyPropertyChanged("PartyNames");
        NotifyPropertyChanged("PartyShortNames");
        NotifyPropertyChanged("Count");
    }

    Party _Party;
    public Party Party
    {
        get { return _Party; }
        set
        {
            _Party = value;
            NotifyPropertyChanged("Party");
            NotifyPropertyChanged("Count");
        }
    }

    public string Count
    {
        get
        {
            var list = Parties.ToList();
            list.RemoveAll(x =&gt; x.IsEmpty());
            int current = list.FindIndex(x =&gt; x == Party) + 1;
            int count = list.Count();
            if (current == 0)
                return string.Format("{0} of {0}", count + 1);
            else
                return string.Format("{0} of {1}", current, count);
        }
    }

    public RelayCommand PrevCommand { get; set; }
    public bool CanPressPrev() { return IndexOf(Party) &gt; 0; }
    public void PrevPressed()
    {
        try
        {
            int i = IndexOf(Party);
            Party = Parties[i - 1];
        }
        catch (Exception ex) { Message.ShowError(ex); }
    }

    public RelayCommand NextCommand { get; set; }
    public bool CanPressNext() { return !Party.IsNullOrEmpty() &amp;&amp; IndexOf(Party) != MaxParties; }
    public void NextPressed()
    {
        try
        {
            if (IndexOf(Party) + 1 == Parties.Count)
            {
                Party = new Party();
                Parties.Add(Party);
            }
            else
            {
                int i = IndexOf(Party);
                Party = Parties[i + 1];
            }
        }
        catch (Exception ex) { Message.ShowError(ex); }
    }

    public RelayCommand ClearCommand { get; set; }
    public bool CanClear()
    {
        return !Party.IsNullOrEmpty();
    }
    public void ClearPressed()
    {
        try
        {
            int i = IndexOf(Party);
            if (Party == Parties.Last())
                Party.Clear();
            else
            {
                Parties.RemoveAll(x =&gt; x == Party);
                Party = Parties[i];
            }
        }
        catch (Exception ex) { Message.ShowError(ex); }
    }

    int IndexOf(Party party) { return Parties.ToList().FindIndex(x =&gt; x == party); }

    public static List&lt;string&gt; PartyTypes { get { return new List&lt;string&gt;() { "Individual", "Company", "Partnership" }; } }

    public bool IsCompany { get; set; }
}
A couple of comments:


It looks like the class only manages parties. This is nice SRP.
Use StyleCop, it makes code much easier to read and review.
Validate inputs, makes it much faster to find and fix bugs:

public PartiesViewModel(ObservableCollection&lt;Party&gt; parties)
{
    if (parties == null)
    {
        throw new ArgumentNullException(nameof(parties));
    }
    ...

Party = Parties.FirstOrCreateIfEmpty(); without knowing what this extension method does I don't love it as it requires me to navigate to another place in the code to see what it does. I guess it does something like this:

Party = Parties.FirstOrDefault() ?? new Party(...);

If this is the case I think you should drop the extension method.
Party.PropertyChanged += UpdatePartyShortNamesList;

I can't see that this subscription is updated anywhere. I would expect the subscription to be removed from the old party and added to the new party in the setter for Party. As it is now it is probably a bug and a memory leak.
public ObservableCollection&lt;Party&gt; Parties { get; set; } a public setter here suggests that the collection can be replaced (without notifying the view about it). I assume you want it to be a readonly property. This also applies to the command properties. 

In C#6 you express this as:

public ObservableCollection&lt;Party&gt; Parties { get; }

Prior to C#6 this was slightly more verbose:

private readonly ObservableCollection&lt;Party&gt; _parties;

public PartiesViewModel(ObservableCollection&lt;Party&gt; parties)
{
    _parties = parties;
}

public ObservableCollection&lt;Party&gt; Parties
{
    get { return _parties; }
}


Being explicit about what is readonly is a very good habit as it makes code easier to reason about and lets the compiler catch more bugs.
I have a feeling that binding SelectedIndex can simplify things a lot.
The command methods CanPressPrev etc. shall probably be private as the commands are normally the exposed means to interact with the viewmodel.
About reuse, this class looks like a nice candidate for composing with. Inject it in other viewmodels where the contact list is needed.


This got long, ending here.