0

这篇文章的最终目标是覆盖通用基类的具体实现的 ToString() 方法,同时仍然能够使用 Linq 展平技术搜索实现。因此,如果您阅读本文并看到更好的方法,请告诉我。我正在为 Silverlight 使用 Telerik 控件,它们不会更改其 api 以允许其某些控件属性是数据绑定的,而是依赖于它们绑定到的任何对象的 ToString() 方法。是的,愚蠢的..无论如何,这就是我所拥有的。

我的页面上的 RadTreeView 控件。树视图中每个节点的 FullPath 属性使用其绑定到的每个项目的 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 Ria 服务)

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();
4

1 回答 1

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));
        }
    }
于 2010-08-18T07:32:11.133 回答