0

I want to create a custom ObservableCollection<string> to use with MVVM in WPF. My actual goal is to extend the standard ObservableCollection<string> by two properties, which return the selected index and the selected item, as well as by a method that checks whether a given string is in the Collection. It currently looks like this:

public class MyStringCollection : ObservableCollection<string>
{
    private int _selectedIndex;
    private ObservableCollection<string> _strings;

    public MyStringCollection() : base()
    {
        _selectedIndex = 0;
        _strings = new ObservableCollection<string>();
    }

    /// <summary>
    /// Index selected by the user
    /// </summary>
    public int SelectedIndex
    {
        get { return _selectedIndex; }
        set { _selectedIndex = value; }
    }

    /// <summary>
    /// Item selected by the user
    /// </summary>
    public string Selected
    {
        get { return _strings[SelectedIndex]; }
    }

    /// <summary>
    /// Check if MyStringCollection contains the specified string
    /// </summary>
    /// <param name="str">The specified string to check</param>
    /// <returns></returns>
    public bool Contains(string str)
    {
        return (_strings.Any(c => (String.Compare(str, c) == 0)));
    }        
}

Even though MyStringCollection inherits from ObservableCollection<string>, the standard methods, such as Add, Clear, etc., won't work. Of course, that is because I create a separate instance _strings each time I create an instance of MyStringCollection.

My question is how to add/clear elements to/from my ObservableCollection<string>() without adding those functions manually?

berti
  • 127
  • 1
  • 15
  • FYI, if you can use LINQ, you don't need to define your own `Contains` method. Just add `using System.Linq;` and you'll be able to use the IEnumerable extension method `Contains` on your `ObservableCollection`. http://msdn.microsoft.com/en-us/library/system.linq.enumerable.contains(v=vs.100).aspx – Wyatt Earp Nov 20 '14 at 14:23

2 Answers2

0

You have derived from ObservableCollection<T> so this is a reference to your collection. All you need is

public string Selected
{
    get { return this[SelectedIndex]; }
}

and

public bool Contains(string str)
{
    return (this.Any(c => (String.Compare(str, c) == 0)));
}        

Note that Contains() already exists as an extension method.

Tim Rogers
  • 21,297
  • 6
  • 52
  • 68
  • Thanks! You're right that `Contains()` already exists as an extension method; however, it uses the Equals on object, which simply checks whether the memory addresses are the same. In contrast, I want to check whether the content of the string is the same. – berti Nov 20 '14 at 14:49
  • In C#, String.Equals(string) compares the value of the string; not the memory address. http://msdn.microsoft.com/en-us/library/fbh501kz%28v=vs.110%29.aspx – Wyatt Earp Nov 20 '14 at 16:58
0

I'm not sure about what you're trying to achieve, but you shouldn't inherit from ObservableCollection<string>, prefer composition over inheritance. Actually you've already almost done it (you already have a private ObservableCollection<string> _strings member).

See for example: Prefer composition over inheritance?

Back to your initial requirement, if you're doing MVVM, most probably you want to expose both a ObservableCollection<T> MyObjects property and a T MySelectedObject property.

Community
  • 1
  • 1
ken2k
  • 48,145
  • 10
  • 116
  • 176