如何继承WPF控件并在C#中同时使用泛型类?

时间:2017-02-01 15:49:55

标签: c# wpf generics inheritance

它从一个泛型类开始,然后我从那个继承。现在我有了一个Node,它将在稍后的阶段直观呈现。我的计划是继承Thumb控件以允许我的节点支持拖动,但现在问题是C#不支持多继承。所以我此时唯一的选择似乎就是废弃我的代码并从Thumb继承基类(由于我计划使用不支持Thumb类功能的某些Node类,我不喜欢这样做) )。我没有办法使用我的泛型类,同时继承Thumb类(WPF)的功能吗?能够继承Node以创建更专业的类非常好,这些类也可以支持像Thumb这样的WPF控件的功能。

public class BaseNode<T> where T : BaseNode<T>
{
    private T _item;
    private T _parent;
    private List<BaseNode<T>> _children;

    public T Item
    {
        get { return _item; }
        set { _item = value; }
    }

    public BaseNode(T item)
    {
        _item = item;
    }
    public void SetParent(T parent)
    {
        _parent.Item = parent;
    }
    public void AddChild(T child)
    {
        _children.Add(new BaseNode<T>(child));
    }
    public void RemoveChild(T child)
    {
        var node = _children.FirstOrDefault(e => e.Item.Equals(child));
        if (node != null)
            _children.Remove(node);
    }
}

public class Node : BaseNode<Node>
{
    private Node _item;
    private List<NodeElement> NodeElements;

    Node (Node item) : base(item)
    {
        _item = item;
    }

    public void ResetElements()
    {
        NodeElements.ForEach(e => e.ResetState());
    }

    public void AddElement(NodeElement element)
    {
        NodeElements.Add(element);
    }

    public void RemoveElement(NodeElement element)
    {
        var elem = NodeElements.FirstOrDefault(e => e.Equals(element));
        if (elem != null)
            NodeElements.Remove(elem);
    }
}

1 个答案:

答案 0 :(得分:2)

如果您想创建自定义Thumb,您的班级应该继承自Thumb。然后,您可以使用合成来使用您的泛型类。像这样:

public interface INode<T>
{
    T Item { get; set; }
    void SetParent(T parent);
    void AddChild(T child);
    void RemoveChild(T child);
}

public class BaseNode<T> where T : INode<T>
{
    private T _item;
    private T _parent;
    private List<BaseNode<T>> _children;

    public T Item
    {
        get { return _item; }
        set { _item = value; }
    }

    public BaseNode(T item)
    {
        _item = item;
    }
    public void SetParent(T parent)
    {
        _parent.Item = parent;
    }
    public void AddChild(T child)
    {
        _children.Add(new BaseNode<T>(child));
    }
    public void RemoveChild(T child)
    {
        var node = _children.FirstOrDefault(e => e.Item.Equals(child));
        if (node != null)
            _children.Remove(node);
    }
}

public class Node : Thumb, INode<Node>
{
    private Node _item;
    private List<NodeElement> NodeElements;
    private readonly BaseNode<Node> _base;

    public Node()
    {
        _base = new BaseNode<Node>(this);
    }

    public void ResetElements()
    {
        NodeElements.ForEach(e => e.ResetState());
    }

    public void AddElement(NodeElement element)
    {
        NodeElements.Add(element);
    }

    public void RemoveElement(NodeElement element)
    {
        var elem = NodeElements.FirstOrDefault(e => e.Equals(element));
        if (elem != null)
            NodeElements.Remove(elem);
    }

    public Node Item
    {
        get { return _base.Item; }
        set { _base.Item = value; }
    }

    public void SetParent(Node parent)
    {
        _base.SetParent(parent);
    }
    public void AddChild(Node child)
    {
        _base.AddChild(child);
    }
    public void RemoveChild(Node child)
    {
        _base.RemoveChild(child);
    }
}

包含自定义控件的所有节点都实现了INode<T>接口。