How to select TreeViewItem data file?

I have an XML binding to a TreeView with an XmlDataProvider. If I add a subnode to the XML that TreeView shows, but how can I select this element?

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> 
0
source share
3 answers

Late, so my functions are not the smoothest, but they work! I commented on this for everyone who had the same problem :-)

Usings:

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

Functions:

 /// <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; } } 
0
source

I have a first approach:

 ((treeView.ItemContainerGenerator.ContainerFromIndex(1) as TreeViewItem).ItemContainerGenerator.ContainerFromItem(newNode) as TreeViewItem).IsSelected = true; 

this selects newNode if I add it to the category at position 1, otherwise I will become an exception; -)

Now I work dynamically once with more than one level :-)

0
source

Source: https://habr.com/ru/post/1400455/


All Articles