2017-02-01 3 views
2

それは汎用クラスで始まり、それから継承します。今では、後で視覚的に表現されるノードがあります。私の計画では、Thumbコントロールから継承して、ノードがドラッグをサポートできるようにしましたが、問題は複数の継承がC#ではサポートされていないということです。だから、私の唯一の選択肢は、自分のコードをスクラップして、Thumbから基本クラスを継承することです(Thumbクラスの機能をサポートしていない特定のNodeクラスを持つ計画のために好きではありません)。ジェネリッククラスを使用する方法はありませんが、同時にThumbクラス(WPF)の機能を継承する方法はありますか? ThumbのようなWPFコントロールの機能をサポートすることができる、より特殊化されたクラスを作成するには、Nodeを継承することができればとても良いことです。WPFコントロールから継承し、C#で汎用クラスを同時に使用する方法は?

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); 
    } 
} 

答えて

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); 
    } 
} 

すべてのノードは、カスタムコントロールをinclucingはINode<T>インタフェースを実装しています。

+0

ありがとうございます。それは非常に良い答えです。以前は構図のコンセプトは紹介されていませんでした。 – Pelle

関連する問題