2016-03-25 6 views
0

Ich habe eine Basisklasse:einfachste Art und Weise über das Objekt rekursiv Baumes

public abstract class BaseClass{ 
    public bool IsSelected {get; set;} 
} 

Eine abgeleitete Klasse mit einer Sammlung eine Hierarchie darstellen:

public class DerivedOne : BaseClass{ 
    public ObservableCollection<BaseClass> Children {get; set;} 
} 

andere abgeleitete Klasse:

public class DerivedTwo : BaseClass{ 

} 

Was ist der einfachste Weg, um alle Elemente unter einem DerivedOne Wurzel zu finden, die IsSelected auf True gesetzt haben?

Antwort

1

Sie links eine Anforderung Detail, aber ich denke, so etwas wie dies funktionieren sollte:

public IEnumerable<BaseClass> AllIsSelected(BaseClass root) 
{ 
    if (root.IsSelected) 
    { 
     yield return root; 
    } 
    var composite = root as DerivedOne; 
    if (composite != null) 
    { 
     foreach (var v in composite.Children) 
     { 
      foreach (var x in AllIsSelected(v)) 
      { 
       yield return x; 
      } 
     } 
    } 
} 

Natürlich, wenn Sie auf einmal eine vollständige Liste möchten, können Sie die Liste der mit ‚Ertrag statt bauen könnte ".

Dies ist das gleiche Design wie hier beschrieben: IEnumerable and Recursion using yield return.

Wie eine andere Antwort sagte, können Sie LINQ verwenden, um dies etwas zu verkürzen. Diese Version vermeidet das Erstellen der temporären Liste.

public IEnumerable<BaseClass> AllIsSelected(BaseClass root) 
    { 
     if (root.IsSelected) 
     { 
      yield return root; 
     } 
     var composite = root as DerivedOne; 
     if (composite != null) 
     { 
      foreach (var x in composite.Children.SelectMany(v => AllIsSelected(v))) 
      { 
       yield return x; 
      } 
     } 
    } 
+0

Wenn eines der Kinder ebenfalls ein DerivedOne ist, ignoriert dieser Ansatz seine Kinder. Soweit ich die Frage verstehe, sollten diese ebenfalls durchlaufen werden. Ich nehme an, Sie brauchen entweder eine Art Stack oder Rekursion. – timcbaoth

+1

@timcbaoth Danke, ich habe den Code bearbeitet, um die Kinder korrekt zu iterieren. –

0

Die einfachste Methode wäre LINQ zu verwenden, um mit Rekursion

public IEnumerable<BaseClass> GetAllSelectedChildren(DerivedOne derivedOne) 
{ 
    return derivedOne.Children.SelectMany(GetAllSelected); 
} 

public IEnumerable<BaseClass> GetAllSelected(BaseClass baseClass) 
{ 
    var selected = new List<BaseClass>(); 

    if(baseClass.IsSelected) 
    { 
     selected.Add(baseClass); 
    } 

    var derivedOne = baseClass as DerivedOne; 
    if(derivedOne != null) 
    { 
     selected.AddRange(GetAllSelectedChildren(derivedOne)); 
    } 

    return selected; 
} 
0

Verwenden Sie einfache Linq.

+0

Wird dies den Baum beliebig tief scannen? Ich denke, es wird nur eine zusätzliche Ebene gehen. Es erfordert auch, dass ** root ** eine ** DerivedOne ** sein muss (was tatsächlich eine Einschränkung in den Anforderungen war). Der allgemeinere Fall ist, dass ** root ** eine beliebige ** BaseClass ** sein kann. –

Verwandte Themen