如何选择一个数据绑定的TreeViewItem? [英] How to select a databound TreeViewItem?

查看:152
本文介绍了如何选择一个数据绑定的TreeViewItem?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个XML数据绑定到TreeView与XmlDataProvider。如果我向TreeView添加一个子节点,TreeView会显示它,但是如何选择这个项目?



XAML:

 < Window.Resources> 
< HierarchicalDataTemplate DataType =categoryItemsSource ={Binding XPath = child :: node()}>
< TextBlock Text ={Binding XPath = @ name}FontWeight =Bold/>
< / HierarchicalDataTemplate>

< HierarchicalDataTemplate DataType =card>
< TextBlock Text ={Binding XPath =。/ title}FontStyle =Italic/>
< / HierarchicalDataTemplate>

< XmlDataProvider x:Key =dataxmlXPath =root / cards/>

< /Window.Resources>

< TreeView Name =treeView
ItemsSource ={Binding Source = {StaticResource dataxml},
XPath =。/ *,
UpdateSourceTrigger = PropertyChanged}
/>

CS:

 code> public partial class MainWindow:Window 
{
XmlDataProvider xmlDataProvider = new XmlDataProvider();

public MainWindow()
{
InitializeComponent();
xmlDataProvider = this.FindResource(dataxml)作为XmlDataProvider;
xmlDataProvider.Source = new Uri(System.IO.Path.GetFullPath(fullPathToXml),UriKind.Absolute);
xmlDataProvider.Refresh();
}

public void AddChild()
{
XmlNode newNode = xmlDataProvider.Document.CreateElement(card);
XmlNode selectedItem =(XmlNode)treeView.SelectedItem;

if(selectedItem!= null)
{
//将newNode作为子选项添加到所选的
selectedItem.AppendChild(newNode);
//选择子节点(newNode)??? < =====
}
else
{
//将newNode作为子代添加到rootnode并选择它:
xmlDataProvider.Document.DocumentElement [ card]。AppendChild(newNode);
(treeView.ItemContainerGenerator.ContainerFromItem(newNode)作为TreeViewItem).IsSelected = true;
}

xmlDataProvider.Document.Save(fullPathToXml);
xmlDataProvider.Refresh();
}
}

XML:

 < root> 
< settings>
....
..
< / settings>
<卡>
< category name =C1>
< card name =card1>
< question> bla< / question>
< answer> blub< / answer>
< / card>
< category name =C2>
< card name =card4>
< question> bla< / question>
< answer> blub< / answer>
< / card>
< / category>
< / category>
< card name =card2>
< question> bla< / question>
< answer> blub< / answer>
< / card>
< card name =card3>
< question> bla< / question>
< answer> blub< / answer>
< / card>
< / cards>
< / root>


解决方案

迟到了,所以我的功能不是最流畅,但它的作品!
我已经评论过一次有同样的问题; - )



使用:

  using System; 
使用System.Collections.Generic;
使用System.Linq;
使用System.Windows.Controls;
使用System.Xml;
使用System.Runtime.InteropServices;

功能:

 code> ///< summary> 
///在TreeView中选择一个XmlNode,该数据绑定到xmlDataProvider。
///< / summary>
///< param name =treeView> TreeView的引用。< / param>
///< param name =node>要选择的节点。< / param>
public static void SelectTreeViewNode(ref TreeView treeView,XmlNode node)
{
if(treeView.HasItems)
{
//转换为xml节点
var xmlNodeList = treeView.Items.Cast< XmlNode>(); ;

//根级别的节点? - >选择它
如果(xmlNodeList.Contains(node))
{
(treeView.ItemContainerGenerator.ContainerFromItem(node)as TreeViewItem).IsSelected = true;
}
else
{
//获取rootnode
XmlNode根节点= GetRootNode(node,xmlNodeList);

//获取父节点列表
列表< XmlNode> parentNodes = new List< XmlNode>();
GetAllParentNodes(rootNode,node,ref parentNodes);
parentNodes.Reverse();

// finaly,选择节点
SelectNode(parentNodes,node,ref treeView,null);
}

}
}

///< summary>
///循环递归到父节点,直到找到xmlNodeList中的节点。
///如果他找不到任何东西,则返回null。
///< / summary>
///< param name =node>起始节点< / param>
///< param name =xmlNodeList>具有可能根节点的列表< / param>
///< returns>根节点< / returns>
private static XmlNode GetRootNode(XmlNode node,IEnumerable< XmlNode> xmlNodeList)
{
if(!xmlNodeList.Contains(node)&& node.ParentNode!= null)
{
return GetRootNode(node.ParentNode,xmlNodeList);
}
else if(xmlNodeList.Contains(node))返回节点;
else return null;
}

///< summary>
///从根节点内的实际节点返回所有父节点。工作递归。
///< / summary>
///< param name =rootNode>根节点< / param>
///< param name =actualNode> startnode< / param>
///< param name =parentNodes>输出列表的rererenz< / param>
private static void GetAllParentNodes(XmlNode rootNode,XmlNode actualNode,ref List< XmlNode> parentNodes)
{
if(actualNode.ParentNode!= null&!actualNode.Equals(rootNode) )
{
parentNodes.Add(actualNode.ParentNode);
GetAllParentNodes(rootNode,actualNode.ParentNode,ref parentNodes);
}
}

///< summary>
///从一个数据绑定到一个xmlDataProvider的TreeView中选择一个XmlNode。
///< / summary>
///< param name =parentNodes>列表中的所有父节点都是rootnode。< / param>
///< param name =node>要选择的节点。< / param>
///< param name =treeView> TreeView的引用。< / param>
///< param name =item>递归的变量。< / param>
private static void SelectNode(List< XmlNode> parentNodes,XmlNode node,ref TreeView treeView,[可选,DefaultParameterValue(null)] TreeViewItem项)
{
if(parentNodes.Count> 0 )
{
TreeViewItem tvItem;
if(item!= null)
tvItem = item.ItemContainerGenerator.ContainerFromItem(parentNodes.First())作为TreeViewItem;
else
tvItem = treeView.ItemContainerGenerator.ContainerFromItem(parentNodes.First())作为TreeViewItem;
parentNodes.RemoveAt(0);
SelectNode(parentNodes,node,ref treeView,tvItem);
}
else if(item!= null)
{
(item.ItemContainerGenerator.ContainerFromItem(node)as TreeViewItem).IsSelected = true;
}
}


I have a XML databound to a TreeView with a XmlDataProvider. If i add a subnode to the XML the TreeView shows it, but how can i select this item?

XAML:

<Window.Resources>
    <HierarchicalDataTemplate DataType="category" ItemsSource="{Binding XPath=child::node()}">
        <TextBlock Text="{Binding XPath=@name}" FontWeight="Bold" />
    </HierarchicalDataTemplate>

    <HierarchicalDataTemplate DataType="card">
        <TextBlock Text="{Binding XPath=./title}" FontStyle="Italic" />
    </HierarchicalDataTemplate>

    <XmlDataProvider x:Key="dataxml" XPath="root/cards"/>

</Window.Resources>

 <TreeView  Name="treeView" 
            ItemsSource="{Binding Source={StaticResource dataxml}, 
                          XPath=./*, 
                          UpdateSourceTrigger=PropertyChanged}"
 />

CS:

public partial class MainWindow : Window
{
    XmlDataProvider xmlDataProvider = new XmlDataProvider();

    public MainWindow()
    {
        InitializeComponent();           
        xmlDataProvider = this.FindResource("dataxml") as XmlDataProvider;
        xmlDataProvider.Source = new Uri(System.IO.Path.GetFullPath(fullPathToXml), UriKind.Absolute);
        xmlDataProvider.Refresh();
    }

    public void AddChild()
    {
        XmlNode newNode = xmlDataProvider.Document.CreateElement("card");
        XmlNode selectedItem = (XmlNode)treeView.SelectedItem;

        if (selectedItem != null)
        {
            //add the newNode as child to the selected
            selectedItem.AppendChild(newNode);
            //select the childnode (newNode) ?????       <=====
        }
        else
        {
            //add the newNode as child to the rootnode and select it:
            xmlDataProvider.Document.DocumentElement["cards"].AppendChild(newNode);
            (treeView.ItemContainerGenerator.ContainerFromItem(newNode) as TreeViewItem).IsSelected = true;
        }

        xmlDataProvider.Document.Save(fullPathToXml);
        xmlDataProvider.Refresh();
    }
}

XML:

<root>
  <settings>
    ....
    ..
  </settings>
  <cards>
    <category name="C1">
        <card name="card1">
            <question>bla</question>
            <answer>blub</answer>
        </card>
        <category name="C2">
            <card name="card4">
                <question>bla</question>
                <answer>blub</answer>
            </card>
        </category>
    </category>
        <card name="card2">
            <question>bla</question>
            <answer>blub</answer>
        </card>
        <card name="card3">
            <question>bla</question>
            <answer>blub</answer>
        </card>
  </cards>
</root>

解决方案

It is late, so my functions arent the smoothest, but it works! I have comment it for all that once have the same problem ;-)

Usings:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Controls;
using System.Xml;
using System.Runtime.InteropServices;

Function:

/// <summary>
/// Select a XmlNode in a TreeView that is databound to a xmlDataProvider.
/// </summary>
/// <param name="treeView">A referenz to the TreeView.</param>
/// <param name="node">The node to select.</param>
public static void SelectTreeViewNode(ref TreeView treeView, XmlNode node)
{
    if (treeView.HasItems)
    {
        //cast to xml-nodes
        var xmlNodeList = treeView.Items.Cast<XmlNode>(); ;

        //node at root level? -> select it
        if (xmlNodeList.Contains(node))
        {
            (treeView.ItemContainerGenerator.ContainerFromItem(node) as TreeViewItem).IsSelected = true;
        }
        else
        {
            //get rootnode
            XmlNode rootNode =  GetRootNode(node, xmlNodeList);

            //get a list of parent nodes
            List<XmlNode> parentNodes = new List<XmlNode>();
            GetAllParentNodes(rootNode, node, ref parentNodes);
            parentNodes.Reverse();

            //finaly, select the node
            SelectNode(parentNodes, node, ref treeView, null);  
        }

    }
}

/// <summary>
/// Goes recursiv down the parent nodes until he finds a node that is in the xmlNodeList.
/// Returns null if he can´t find anything.
/// </summary>
/// <param name="node">The start node.</param>
/// <param name="xmlNodeList">A list with possible rootnodes.</param>
/// <returns>The rootnode</returns>
private static XmlNode GetRootNode(XmlNode node, IEnumerable<XmlNode> xmlNodeList)
{
    if (!xmlNodeList.Contains(node) && node.ParentNode != null)
    {
        return GetRootNode(node.ParentNode, xmlNodeList);
    }
    else if (xmlNodeList.Contains(node)) return node;
    else return null;
}

/// <summary>
/// Returns all parent nodes from the actual node within the rootNode. Works recursiv.
/// </summary>
/// <param name="rootNode">The rootnode.</param>
/// <param name="actualNode">The startnode</param>
/// <param name="parentNodes">The rererenz to the outputlist</param>
private static void GetAllParentNodes(XmlNode rootNode, XmlNode actualNode, ref List<XmlNode> parentNodes)
{
    if (actualNode.ParentNode != null && !actualNode.Equals(rootNode))
    {
        parentNodes.Add(actualNode.ParentNode);
        GetAllParentNodes(rootNode, actualNode.ParentNode, ref parentNodes);
    }
}

/// <summary>
/// Select a XmlNode from a TreeView that is databound to a xmlDataProvider.
/// </summary>
/// <param name="parentNodes">All the parent nodes, first in the list is the rootnode.</param>
/// <param name="node">The node to select.</param>
/// <param name="treeView">A referenz to the TreeView.</param>
/// <param name="item">Variable for the recursion.</param>
private static void SelectNode(List<XmlNode> parentNodes, XmlNode node, ref TreeView treeView, [Optional, DefaultParameterValue(null)] TreeViewItem item)
{
    if (parentNodes.Count > 0)
    {
        TreeViewItem tvItem;
        if (item != null)
            tvItem = item.ItemContainerGenerator.ContainerFromItem(parentNodes.First()) as TreeViewItem;
        else 
            tvItem = treeView.ItemContainerGenerator.ContainerFromItem(parentNodes.First()) as TreeViewItem;
        parentNodes.RemoveAt(0);
        SelectNode(parentNodes, node, ref treeView, tvItem);
    }
    else if (item != null)
    {
        (item.ItemContainerGenerator.ContainerFromItem(node) as TreeViewItem).IsSelected = true;
    }
}

这篇关于如何选择一个数据绑定的TreeViewItem?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆