2011-11-16 2 views
0

인덱서가있는 ObservableCollection의 .NET C# 구문은 무엇입니까? 나는 ObservableColletion을 원하고 서수 위치 또는 문자열 이름으로 항목을 참조합니다. 인덱서를 나타 내기 위해 이것을 사용하는 것을 알고 있지만 ObservableCollection에이를 어떻게 넣어야할지 모르겠습니다. 감사합니다.NET 4.0 Indexer with ObservableCollection

답장을 보내 주셔서 감사합니다. 나는 어떻게 ObservableCollection을 만들고 어떻게 인덱서를 생성 하는지를 안다. 나는 그들을 결합하는 방법을 모른다. 서수 및 문자열 인덱스가있는 ObservableCollection에 대한 샘플 코드를 요청합니다.

// create a generic ObservableCollection - I used object, but you can use any Type 
    var collection = new ObservableCollection<object>(); 

    // set the item at the index. 
    collection[0] = new object(); 

문서 ObservableCollection<T>을위한 : 감사합니다 다시

답변

3

ObservableCollection에이 컬렉션에서 상속을 위치 기반 색인 생성.

문자열 기반 인덱싱의 경우 ObservableDictionary의 사람들 구현을 조사 할 수 있습니다.

개인적으로 성능 향상을 위해 ObservableCollection에서 파생 된 HashedObservableCollection을 작성했습니다.이 목록에는 조회 시간 단축을 위해 색인 할 키 사전이 포함되어 있습니다. InsertItem, RemoveItem 및 ClearItems를 재정 의하여 사전을 동기화 상태로 유지합니다.

예를 들어, 키는 모든 유형이 될 수 있지만 키가 변경되지 않는다고 가정합니다. 항목이 바뀌면 동일한 키를 가진 객체로 바뀝니다. 이 작업을 단순화하려면 TKey를 String으로 바꿀 수 있습니다.

코드 :

여기
using System; 
using System.Linq; 
using System.Collections.Generic; 
using System.Collections.ObjectModel; 

namespace foson.Utils 
{ 
    /// <summary> 
    /// Represents BindableCollection indexed by a dictionary to improve lookup/replace performance. 
    /// </summary> 
    /// <remarks> 
    /// Assumes that the key will not change and is unique for each element in the collection. 
    /// Collection is not thread-safe, so calls should be made single-threaded. 
    /// </remarks> 
    /// <typeparam name="TValue">The type of elements contained in the BindableCollection</typeparam> 
    /// <typeparam name="TKey">The type of the indexing key</typeparam> 
    public class HashedBindableCollection<TValue, TKey> : ObservableCollection<TValue> 
    { 

     protected internal Dictionary<TKey, int> indecies = new Dictionary<TKey, int>(); 
     protected internal Func<TValue, TKey> _keySelector; 

     /// <summary> 
     /// Create new HashedBindableCollection 
     /// </summary> 
     /// <param name="keySelector">Selector function to create key from value</param> 
     public HashedBindableCollection(Func<TValue, TKey> keySelector) 
      : base() 
     { 
      if (keySelector == null) throw new ArgumentException("keySelector"); 
      _keySelector = keySelector; 
     } 

     #region Protected Methods 
     protected override void InsertItem(int index, TValue item) 
     { 
      var key = _keySelector(item); 
      if (indecies.ContainsKey(key)) 
       throw new DuplicateKeyException(key.ToString()); 

      if (index != this.Count) 
      { 
       foreach (var k in indecies.Keys.Where(k => indecies[k] >= index).ToList()) 
       { 
        indecies[k]++; 
       } 
      } 

      base.InsertItem(index, item); 
      indecies[key] = index; 

     } 

     protected override void ClearItems() 
     { 
      base.ClearItems(); 
      indecies.Clear(); 
     } 


     protected override void RemoveItem(int index) 
     { 
      var item = this[index]; 
      var key = _keySelector(item); 

      base.RemoveItem(index); 

      indecies.Remove(key); 

      foreach (var k in indecies.Keys.Where(k => indecies[k] > index).ToList()) 
      { 
       indecies[k]--; 
      } 
     } 
     #endregion 

     public virtual bool ContainsKey(TKey key) 
     { 
      return indecies.ContainsKey(key); 
     } 

     /// <summary> 
     /// Gets or sets the element with the specified key. If setting a new value, new value must have same key. 
     /// </summary> 
     /// <param name="key">Key of element to replace</param> 
     /// <returns></returns> 
     public virtual TValue this[TKey key] 
     { 

      get { return this[indecies[key]]; } 
      set 
      { 
       //confirm key matches 
       if (!_keySelector(value).Equals(key)) 
        throw new InvalidOperationException("Key of new value does not match"); 

       if (!indecies.ContainsKey(key)) 
       { 
        this.Add(value); 
       } 
       else 
       { 
        this[indecies[key]] = value; 
       } 
      } 
     } 

     /// <summary> 
     /// Replaces element at given key with new value. New value must have same key. 
     /// </summary> 
     /// <param name="key">Key of element to replace</param> 
     /// <param name="value">New value</param> 
     /// 
     /// <exception cref="InvalidOperationException"></exception> 
     /// <returns>False if key not found</returns> 
     public virtual bool Replace(TKey key, TValue value) 
     { 
      if (!indecies.ContainsKey(key)) return false; 
      //confirm key matches 
      if (!_keySelector(value).Equals(key)) 
       throw new InvalidOperationException("Key of new value does not match"); 

      this[indecies[key]] = value; 
      return true; 

     } 

     public virtual bool Remove(TKey key) 
     { 
      if (!indecies.ContainsKey(key)) return false; 

      this.RemoveAt(indecies[key]); 
      return true; 

     } 

    } 
    public class DuplicateKeyException : Exception 
    { 

     public string Key { get; private set; } 
     public DuplicateKeyException(string key) 
      : base("Attempted to insert duplicate key " + key + " in collection") 
     { 
      Key = key; 
     } 
    } 
} 
+0

자세한 내용이 필요합니다.ordinal 및 string 인덱스가있는 ObservableCollection의 C# 구문입니다. – Paparazzi

+0

'public 가상 TValue this [TKey key]'메소드를 살펴보십시오. 각 오버로드가 다른 매개 변수 유형을 가지고있는 한 인덱서 함수 ('public XXX this [YYY]')를 여러 번 오버로드 할 수 있습니다. – foson

+0

굉장! 그 생성자를 정말로 좋아합니다. ObservableCollection에서 상속 받음으로써 서수 부분을 처리합니다. – Paparazzi

0

을 사용할 수 있습니다 : http://msdn.microsoft.com/en-us/library/ms668604.aspx

설명서에 대한 색인 생성기 'Item'속성) :

귀하의 의견에 따르면 이 아닌 ObservableDictionary을 찾고있는 것 같습니다. .NET은 내장 등의 컬렉션을 가지고 있지 않지만 빠른 구글 검색은이 두 가지 구현 발견 : 이미 가지고 있으므로,

+0

그 링크 모음에 대한 서수 인덱스를 찾는 데 도움이되기를 바랍니다. 문제는 ordinal 및 string 인덱스가있는 ObservableCollection의 C# 구문입니다. – Paparazzi

+0

@BalamBalam, ObservableCollection 클래스는 문자열 값으로 인덱싱되지 않습니다. 관측 가능한 컬렉션의 인덱스에 해당하는 인덱스를 사용하여 문자열 배열을 유지해야합니다. – smartcaveman

+0

@BalamBalam, 업데이트 – smartcaveman

2

내 생각이다, 이것은 솔루션

using System.Collections.ObjectModel; 

namespace WPFValidation 
{ 
    public class CustomObservableCollection<T> : ObservableCollection<T> 
    { 
    public T this[string key] { 
     get { 
     // you must implement some code to do this one 
     T item = GetItemWithAKey(key); 
     return item; 
     } 
     set { 
     T item = GetItemWithAKey(key); 
     if (item != null) { 
      // set the given value toi the item 
      this.SetItemValue(item, value); 
     } 
     } 
    } 

    private T GetItemWithAKey(string key) { 
     // find the item with teh given key 
     return default(T); 
    } 
    } 

    public class TestClass 
    { 
    public TestClass() { 
     var coll = new CustomObservableCollection<CustomKeyedClass>(); 
     coll.Add(new CustomKeyedClass("One")); 
     coll.Add(new CustomKeyedClass("Two")); 
     var item = coll["One"]; 
     var item2 = coll[1]; 
    } 
    } 
} 
+0

GetItemsWithKey는 비어있는 부분입니다. +1 Foson의 답은 내가 필요로하는 것 (나는 생각한다)이다. – Paparazzi

+0

네, 좋은 해결책입니다! – punker76