Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Well, it would be easier if your element hierarchy was more like...</p> <pre><code>&lt;node type="forest"&gt; &lt;node type="tree"&gt; ... </code></pre> <p>...rather than your current schema.</p> <p>As-is, you'll need 4 <code>HierarchicalDataTemplate</code>s, one for each hierarchical element including the root, and one <code>DataTemplate</code> for <code>leaf</code> elements:</p> <pre><code>&lt;Window.Resources&gt; &lt;HierarchicalDataTemplate DataType="forestPad" ItemsSource="{Binding XPath=forest}"&gt; &lt;TextBlock Text="a forestpad" /&gt; &lt;/HierarchicalDataTemplate&gt; &lt;HierarchicalDataTemplate DataType="forest" ItemsSource="{Binding XPath=tree}"&gt; &lt;TextBox Text="{Binding XPath=data}" /&gt; &lt;/HierarchicalDataTemplate&gt; &lt;HierarchicalDataTemplate DataType="tree" ItemsSource="{Binding XPath=branch}"&gt; &lt;TextBox Text="{Binding XPath=data}" /&gt; &lt;/HierarchicalDataTemplate&gt; &lt;HierarchicalDataTemplate DataType="branch" ItemsSource="{Binding XPath=leaf}"&gt; &lt;TextBox Text="{Binding XPath=data}" /&gt; &lt;/HierarchicalDataTemplate&gt; &lt;DataTemplate DataType="leaf"&gt; &lt;TextBox Text="{Binding XPath=data}" /&gt; &lt;/DataTemplate&gt; &lt;XmlDataProvider x:Key="dataxml" XPath="forestPad" Source="D:\fp.xml"&gt; &lt;/XmlDataProvider&gt; &lt;/Window.Resources&gt; </code></pre> <p>You can instead set the <code>Source</code> of the <code>XmlDataProvider</code> programmatically:</p> <pre><code>dp = this.FindResource( "dataxml" ) as XmlDataProvider; dp.Source = new Uri( @"D:\fp.xml" ); </code></pre> <p>Also, re-saving your edits is as easy as this:</p> <pre><code>dp.Document.Save( dp.Source.LocalPath ); </code></pre> <p>The <code>TreeView</code> itself needs a <code>Name</code> and an <code>ItemsSource</code> bonded to the <code>XmlDataProvider</code>:</p> <pre><code>&lt;TreeView Name="treeview" ItemsSource="{Binding Source={StaticResource dataxml}, XPath=.}"&gt; </code></pre> <p>I this example, I did <code>TwoWay</code> binding with <code>TextBox</code>es on each node, but when it comes to editing just one node at a time in a separate, single <code>TextBox</code> or other control, you would be binding it to the currently selected item of the <code>TreeView</code>. You would also change the above <code>TextBox</code>es to <code>TextBlock</code>s, as clicking in the <code>TextBox</code> does not actually select the corresponding <code>TreeViewItem</code>.</p> <pre><code>&lt;TextBox DataContext="{Binding ElementName=treeview, Path=SelectedItem}" Text="{Binding XPath=data, UpdateSourceTrigger=PropertyChanged}"/&gt; </code></pre> <p>The reason you must use two <code>Binding</code>s is that you cannot use <code>Path</code> and <code>XPath</code> together.</p> <p><strong>Edit:</strong></p> <p>Timothy Lee Russell asked about saving CDATA to the data elements. First, a little on <code>InnerXml</code> and <code>InnerText</code>.</p> <p>Behind the scenes, <code>XmlDataProvider</code> is using an <code>XmlDocument</code>, with it's tree of <code>XmlNodes</code>. When a string such as "stuff" is assigned to the <code>InnerXml</code> property of an <code>XmlNode</code>, then those tags are really tags. No escaping is done when getting or setting <code>InnerXml</code>, and it is parsed as XML.</p> <p>However, if it is instead assigned to the <code>InnerText</code> property, the angle brackets will be escaped with entities &amp;lt; and &amp;gt;. The reverse happens when the value is retreived. Entities (like &amp;lt;) are resolved back into characters (like &lt;).</p> <p>Therefore, if the strings we store in the data elements contain XML, entities have been escaped, and we need to undo that simply by retrieving <code>InnerText</code> before adding a CDATA section as the node's child...</p> <pre><code>XmlDocument doc = dp.Document; XmlNodeList nodes = doc.SelectNodes( "//data" ); foreach ( XmlNode node in nodes ) { string data = node.InnerText; node.InnerText = ""; XmlCDataSection cdata = doc.CreateCDataSection( data ); node.AppendChild( cdata ); } doc.Save( dp.Source.LocalPath ); </code></pre> <p>If the node already has a CDATA section and the value has not been changed in any way, then it still has a CDATA section and we essentially replace it with the same. However, through our binding, if we change the value of the data elements contents, it replaces the CDATA in favor of an escaped string. Then we have to fix them.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload