Laden...

Kompositum an TreeView binden

Erstellt von DonStivino vor 8 Jahren Letzter Beitrag vor 8 Jahren 733 Views
D
DonStivino Themenstarter:in
51 Beiträge seit 2014
vor 8 Jahren
Kompositum an TreeView binden

Hallo 🙂

Ich habe das Kompositum - Muster implementiert. Dies erschien mir sinnvoll, da ich eine Reflektion über viele Assemblies durchführe, mit bestimmten Filtern, und hier ja bis auf Eigenschaftsebene belieb tiefe Hierarchien gebildet werden können (Eine Eigenschaft kann ja selbst ein Objekt sein und seinerseits wieder welche beinhalten usw.). Der Baum sieht dann in etwa so aus:
-Assembly1
--- Klasse1
----- Eigenschaft1(ist auch ein Objekt)
------- (...)
--------- String Name
--- Klasse2
----- (...)

-Assembly2
---...
----- String Name

Das Kompositum selbst war eigentlich kein Problem. Soweit funktioniert also alles. Im einfachsten Fall gibt es dann Für jeden Knoten die Eigenschaften "Name" und "Description".

Wie kann ich nun das Kompositum über alle Ebenen an den Namen binden?
Ich habe dabei an das HierarchicalDataTemplate gedacht. Mir ist aber unklar, wie ich dies nutzen soll, da dort ja praktisch die Ebene des Baums immer vorgeben ist (oder?).

Meine Anforderung ist also das Binden einer beliebig tiefen Hierarchie an einen Baum. Kann mir da jemand helfen?

Mein bisheriger Ansatz ist der:

  <TreeView x:Name="treeView"
                  HorizontalAlignment="Stretch"
                  VerticalAlignment="Stretch"
                  Grid.ColumnSpan="1"
                  ItemsSource="{Binding Nodes}">
            <TreeView.Resources>
                <HierarchicalDataTemplate x:Key="treeComposite"
                                          DataType="{x:Type elems:Node}"
                                          ItemsSource="{Binding Children}">
                    <TreeViewItem Header="{Binding Name}"></TreeViewItem>
                </HierarchicalDataTemplate>
                <DataTemplate x:Key="DataTemplate1"
                              DataType="{x:Type elems:Node}">
                    <TreeViewItem Header="{Binding Name}">
                    </TreeViewItem>
                </DataTemplate>
            </TreeView.Resources>
        </TreeView>

Vielen Dank!

D
DonStivino Themenstarter:in
51 Beiträge seit 2014
vor 8 Jahren

Hallo nochmal,

ist mir fast ein wenig peinlich aber jetzt habe ich es nach ziemlich viel ausprobieren doch noch hinbekommen^^

Ich würde euch gerne an der Lösung teilhaben lassen:


<TreeView x:Name="treeView"
                  HorizontalAlignment="Stretch"
                  VerticalAlignment="Stretch"
                  Grid.ColumnSpan="1"
                  ItemsSource="{Binding Nodes}">
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate DataType="{x:Type elems:Node}"
                                          ItemsSource="{Binding Children}">
                    <TextBlock Text="{Binding Name}">
                    </TextBlock>
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>

Eigentlich doch simpel 🙂

Ein Problem habe ich aber dennoch:

Ich habe eine Button, der alle Items erweitern oder wieder verkleinern soll. Leider funktioniert die Konvertierung aber nicht. Wie kann ich das beheben?

Hier ist der Code:


 private void btn_expand_Click(object sender, RoutedEventArgs e)
        {
            var btn = sender as Button;
            if (btn.Content.ToString() == "Expand all") {
                btn.Content = "Minimize all";
                foreach (TreeViewItem item in treeView.Items) {
                    item.IsExpanded = true;
                    expandItems(item);
                }
            } else {
                btn.Content = "Expand all";
                foreach (TreeViewItem item in treeView.Items) {
                    item.IsExpanded = false;
                    unExpandItems(item);
                }
            }
        }

Innerhalb der foreach wird eine InvalidCastException ausgelöst. Ich verstehe ja schon warum, aber wie kann ich es dann dennoch ermöglichen, den gesamten Baum zu erweitern?

Vielen Dank!

H
523 Beiträge seit 2008
vor 8 Jahren

Ich würde der Knoten-Klasse noch die Eigenschaft "IsTreeExpanded" hinzufügen und das ganze via DataBinding lösen:


<TreeView.ItemContainerStyle>
                        <Style TargetType="TreeViewItem">
                            <Setter Property="IsExpanded" Value="{Binding Path= IsTreeExpanded,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
                        </Style>
</TreeView.ItemContainerStyle>

Dann kannst Du einfach Deine Liste "Nodes" durchlaufen und IsTreeExpanded auf true oder false setzen.

Wenn Du bei Deiner Lösung bleiben möchtest, musst Du den Code noch etwas anpassen. Ich kann es gerade nicht testen, es sollte aber so funktionieren:


    foreach (object item in treeView.Items)
    {
        TreeViewItem treeViewItem = treeView.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;
        treeViewItem.IsExpanded = true;
    }
D
DonStivino Themenstarter:in
51 Beiträge seit 2014
vor 8 Jahren

Danke für die schnelle Hilfe 🙂