2010-08-18 2 views
0

Конечной целью этого сообщения является переопределить метод ToString() конкретной реализации базового базового класса, сохраняя при этом возможность выполнять поиск с использованием метода выравнивания Linq. Поэтому, если вы прочтете это и увидите лучший способ, дайте мне знать. Я использую элементы управления Telerik для Silverlight, и они не изменят свой api, чтобы некоторые из свойств управления были привязаны к данным и вместо этого полагались на метод ToString() любого объекта, к которому они привязаны. да, глупо. Во всяком случае, вот что у меня есть.Конкретная реализация базового базового класса и метода расширения

Управление RadTreeView на моей странице. Свойство FullPath каждого узла в treeview использует метод ToString() для каждого элемента, связанного с ним (так что это то, что мне нужно переопределить).

Мне пришлось создать класс «посредника», чтобы улучшить базовый класс модели, чтобы он мог быть привязан как иерархия в древовидном представлении, а затем конкретная реализация этого универсального класса для переопределения ToString(). Теперь проблема в том, что у меня есть расширение Linq, которое взрывается, потому что оно не может преобразовать конкретную реализацию обратно в базовый общий класс. Мне нравятся дженерики, но для меня это слишком много. Нужна помощь в решении проблемы с методом расширения.

Посредник общий класс:

public class HeirarchicalItem<T> : NotifyPropertyChangedBase, INotifyCollectionChanged where T : class 
{ 
    public event NotifyCollectionChangedEventHandler CollectionChanged; 

    public virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs ea) 
    { 
     if (CollectionChanged != null) 
      CollectionChanged(this, ea); 
    } 

    public HeirarchicalItem() { } 

    public HeirarchicalItem(T item) 
    { 
     Item = item; 
    } 

    public HeirarchicalItem(IEnumerable<T> collection) 
    { 
     CopyFrom(collection); 
    } 

    private T _item; 
    public T Item 
    { 
     get 
     { 
      return _item; 
     } 
     set 
     { 
      _item = value; 
      RaisePropertyChanged<HeirarchicalItem<T>>(a => a.Item); 
     } 
    } 

    private ObservableCollection<HeirarchicalItem<T>> _children = new ObservableCollection<HeirarchicalItem<T>>(); 
    public virtual ObservableCollection<HeirarchicalItem<T>> Children 
    { 
     get { return _children; } 
     set 
     { 
      _children = value; 
      RaisePropertyChanged<HeirarchicalItem<T>>(a => a.Children); 
      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); 
     } 
    } 

    private void CopyFrom(IEnumerable<T> collection) 
    { 
     if ((collection != null)) 
     { 
      using (IEnumerator<T> enumerator = collection.GetEnumerator()) 
      { 
       while (enumerator.MoveNext()) 
       { 
        HeirarchicalItem<T> newHeirarchicalItem = new HeirarchicalItem<T>(enumerator.Current); 
        Children.Add(newHeirarchicalItem); 
        RaisePropertyChanged<HeirarchicalItem<T>>(a => a.Children); 
        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add)); 
       } 
      } 
     } 
    } 
} 

Базовая модель класса: (данные челноке и от WCF службы Риа с помощью этого класса)

public class tbl_Path : EntityBase, IFullPath, IEquatable<tbl_Path>, IEqualityComparer<tbl_Path> 
{ 
    public tbl_Path(); 
    public int GetHashCode(tbl_Path obj); 
    public override string ToString(); 

    public DateTime CreateDate { get; set; } 
    public short Depth { get; set; } 
    public string FullPath { get; set; } 
    public bool IsAuthorized { get; set; } 
    public bool IsSelected { get; set; } 
    public string Name { get; set; } 
    public override IEnumerable<Operation> Operations { get; } 
    public int? ParentPathID { get; set; } 
    public int PathID { get; set; } 
    public Guid SecurityKey { get; set; } 
    public EntityCollection<tbl_Configuration> tbl_Configuration { get; set; } 
    public EntityCollection<tbl_Key> tbl_Key { get; set; } 
    public EntityCollection<tbl_SecurityACL> tbl_SecurityACL { get; set; } 
    public EntityCollection<tbl_SecurityInheriting> tbl_SecurityInheriting { get; set; } 
    public EntityCollection<tbl_Variable> tbl_Variable { get; set; } 
} 

Бетон Реализация так, что Я могу переопределить ToString():

public class HeirarchicalPath : HeirarchicalItem<tbl_Path> 
{ 
    public HeirarchicalPath() 
    { 

    } 
    public HeirarchicalPath(tbl_Path item) 
     : base(item) 
    { 

    } 
    public HeirarchicalPath(IEnumerable<tbl_Path> collection) 
     : base(collection) 
    { 

    } 

    public override string ToString() 
    { 
     return Item.Name; **// we override here so Telerik is happy** 
    } 
} 

И наконец, это метод расширения Linq, который взрывается во время компиляции, потому что я представил конкретную реализацию моего базового базового класса.

public static IEnumerable<T> Traverse<T>(this IEnumerable<T> source, Func<T, IEnumerable<T>> fnRecurse) 
    { 
     foreach (T item in source) 
     { 
      yield return item; 

      IEnumerable<T> seqRecurse = fnRecurse(item); 

      if (seqRecurse != null) 
      { 
       foreach (T itemRecurse in Traverse(seqRecurse, fnRecurse)) 
       { 
        yield return itemRecurse; 
       } 
      } 
     } 
    } 

Фактический код, который нарушает: (x.Children выделен с ошибкой)

Cannot implicitly convert type 
'System.Collections.ObjectModel.ObservableCollection<HeirarchicalItem<tbl_Path>>' to 
'System.Collections.Generic.IEnumerable<HeirarchicalPath>'. An explicit conversion 
exists (are you missing a cast?) 


      HeirarchicalPath currentItem = this.Paths.Traverse(x => x.Children).Where(x => x.Item.FullPath == "$/MyFolder/Hello").FirstOrDefault(); 

ответ

0

Фигурные его. Работая над этим весь день и минуты после публикации вопроса, я разрешаю его, как всегда.

Просто нужно добавить этот бит в мою конкретную реализацию и не более ошибок компилятора.

private ObservableCollection<HeirarchicalPath> _children = new ObservableCollection<HeirarchicalPath>(); 
    public new ObservableCollection<HeirarchicalPath> Children 
    { 
     get 
     { 
      return _children; 
     } 
     set 
     { 

      if (value == null) 
       return; 

      _children = value; 
      RaisePropertyChanged<HeirarchicalPath>(a => a.Children); 
      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); 
     } 
    } 
Смежные вопросы