0

私はWPFが初めてで、treeviewを使用してツリーを作成しようとしています。

私がやりたいことは、ツリーを動的に生成することです。各 treeViewItem には、comboBox と textBlock が含まれています。ユーザーがノードを展開すると、アプリはデータ ソースから子ノードの情報を取得します。最後に、ユーザーはチェックボックスで複数のノードを選択できます。

いくつかのオンライン チュートリアルに従って、次のツリーを作成しました。

<Window.Resources>
    <Style TargetType="{x:Type TreeViewItem}">
        <Setter Property="HeaderTemplate">
            <Setter.Value>
                <HierarchicalDataTemplate DataType="{x:Type sotc:TaxNode}" ItemsSource="{Binding Path=Children}">
                    <StackPanel Orientation="Horizontal">
                        <CheckBox Name="chk" Margin="2" Tag="{Binding}"/>
                        <TextBlock Text="{Binding Path=TaxID}" ToolTip="{Binding Path=Lineage}" />
                    </StackPanel>
                </HierarchicalDataTemplate>
            </Setter.Value>
        </Setter>

    </Style>
</Window.Resources>

<Grid>
    <TreeView Margin="25,186,22,46">
        <TreeViewItem Header="Taxonomy Tree" x:Name="_TaxTree" x:FieldModifier="private">
            <TreeViewItem Header="Loading..." TextBlock.FontStyle="Italic"></TreeViewItem>
        </TreeViewItem>
    </TreeView>
</Grid>

そして、選択したコンボボックスを取得するメソッドがあります

private List<CheckBox> GetSelectedCheckBoxes(ItemCollection items)
    {
        var list = new List<CheckBox>();
        foreach (TreeViewItem item in items)
        {
            UIElement element = GetChildControl(item, "chk");
            if (element != null)
            {
                var chk = (CheckBox)element;
                if (chk.IsChecked.HasValue && chk.IsChecked.Value)
                {
                    list.Add(chk);
                }
            }

            List<CheckBox> l = GetSelectedCheckBoxes(item.Items);
            list = list.Concat(l).ToList();
        }

        return list;
    }

    private UIElement GetChildControl(DependencyObject parentObject, string childName)
    {
        UIElement element = null;
        if (parentObject != null)
        {
            int totalChild = VisualTreeHelper.GetChildrenCount(parentObject);
            for (int i = 0; i < totalChild; i++)
            {
                DependencyObject childObject = VisualTreeHelper.GetChild(parentObject, i);

                if (childObject is FrameworkElement &&
                    ((FrameworkElement)childObject).Name == childName)
                {
                    element = childObject as UIElement;
                    break;
                }

                // get its child
                element = GetChildControl(childObject, childName);
                if (element != null) break;
            }
        }

        return element;
    }

しかし、WPF に関する知識が不足しているため、メソッドに渡すべき ItemCollection が何であるかがわかりません。

アドバイスやチュートリアルは大歓迎です。

よい休日を

4

1 に答える 1

0

XAML では、Name プロパティを TreeView に追加できます。

<Grid>
    <TreeView Name="MyAwesomeTreeView" Margin="25,186,22,46">
        <TreeViewItem Header="Taxonomy Tree" x:Name="_TaxTree" x:FieldModifier="private">
            <TreeViewItem Header="Loading..." TextBlock.FontStyle="Italic"></TreeViewItem>
        </TreeViewItem>
    </TreeView>
</Grid>

これで、次のようにコード ビハインドでこのツリービューの項目にアクセスできるようになりました。

ItemCollection myDataItems = MyAwesomeTreeView.Items
GetSelectedCheckBoxes(myDataItems, MyAwesomeTreeView);

ただし、示した方法は、データ テンプレートを使用した TreeView では機能しません。その理由は、TreeView が実際に画面に表示されると、TreeViewItems のみを生成するためです。それまでは、基になるデータのみが含まれます。これを回避するには、TreeView の ItemContainerGenerator を使用する必要があります。チェックボックス メソッドを次のように変更します。

private List<CheckBox> GetSelectedCheckBoxes(ItemCollection items, ItemsControl source)
{
    var list = new List<CheckBox>();
    foreach (object dataitem in items)
    {
        UIElement treeviewitem = source.ItemContainerGenerator.ContainerFromItem(dataitem)
        UIElement element = GetChildControl(treeviewitem, "chk");
        if (element != null)
        {
            var chk = (CheckBox)element;
            if (chk.IsChecked.HasValue && chk.IsChecked.Value)
            {
                list.Add(chk);
            }
        }

        List<CheckBox> l = GetSelectedCheckBoxes(item.Items, treeviewitem);
        list = list.Concat(l).ToList();
    }

    return list;
}

しかし、これは良い方法ではないことを強調したいと思います。あなたが達成しようとしていることは、はるかに単純で簡単で保守可能な方法で達成できるに違いないので、最初にそれが何であるかを説明することをお勧めします.

于 2012-11-22T01:30:34.877 に答える