Wednesday, November 7, 2007

Copy Functionality on a TreeView

In the project I'm working on, I'm using a treeview to display a dump of some xml file. I wanted to be able to add the copy functionality so that users could copy the information and paste it somewhere useful. Because TreeViewItem s do not have this functionality by default I wrote the following code. Hopefully it will be of some use to you.


Call this function on every TreeViewItem you want the copy command to work on



private void AddCopyCommand(ref TreeViewItem tvi)
{
      CommandBinding copyCmdBinding = new CommandBinding();
      copyCmdBinding.Command = ApplicationCommands.Copy;
      copyCmdBinding.Executed += copyCmdBinding_Executed;
      copyCmdBinding.CanExecute += copyCmdBinding_CanExecute;
      tvi.CommandBindings.Add(copyCmdBinding);
}

Alternatively you could do this in xaml with:



<TreeViewItem>
<TreeViewItem.Commandbindings>
<CommandBinding Command="ApplicationCommands.Copy"
     Executed="copyCmdBinding_Executed"
     CanExecute="copyCmdBinding_CanExecute"/>
</TreeViewItem.CommandBindings
</TreeViewItem>


Then you have to write the functions to check for execution and actually execute:



private void copyCmdBinding_Executed (object sender, ExecutedRoutedEventArgs e) {
      // Set text to clip board
      TreeViewItem tvi = (TreeViewItem)sender;
      Clipboard.SetText((String)tvi.Header);
}

private void copyCmdBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
      //Check for text
      TreeViewItem tvi = (TreeViewItem)sender;
      if (tvi.Header != null)
      {
            e.CanExecute = true;
      }
      else
      {
            e.CanExecute = false;
      }
}


Note: This should work on any WPF Control, not just the TreeViewItem.

Thursday, October 18, 2007

Binding a XmlDocument to a TreeView in WPF

So I am working on a project in which I needed to bind a XmlDocument to a TreeView. After hours of staring at the XamlParseError exception (which gives you NO useful information), I finally figured out some of my problems. First off, in order to DataBind the source need to implement IEnumerable. Guess what?? XmlDocument doesn't implement it. So I tried different, to no avail, and I eventually just wrote a (*Gasp*), recursive function to transform a XmlDocument to a TreeView. Didn't think I would ever have to write one of those again! Here it is in all it's glory:

public void CopyXmlToTreeView( XmlNode xNode, ref TreeViewItem tviParent )
{
if (xNode == null)
{
return;
}
if (xNode.HasChildNodes)
{
foreach (XmlNode child in xNode.ChildNodes)
{
TreeViewItem tviChild = new TreeViewItem();
if (child.HasChildNodes)
{
tviChild.Header = child.Name;
tviChild.IsExpanded = true;
tviParent.Items.Add(tviChild);
CopyXmlToTreeView(child, ref tviChild);
}
else if (child.Value != null)
{
tviChild.Header = child.InnerText;
tviParent.Items.Add(tviChild);
}
}
}
}

My WPF Blog

So, in my adventures through learning WPF and .net I have had encountered many a problem. To solve these problems I have looked to the internet, for other people's solutions to these problems. So in the spirit of giving back I have decided to write this blog so that others can benefit from the problems I have already solved (Go Open Source!!) Hopefully someone will benefit from this, and feel free to email me or comment if you have any questions or suggestions!