How do I copy a TreeViewItem onto another that is using an object as a tag and header?

StackOverflow https://stackoverflow.com/questions/12571008

  •  03-07-2021
  •  | 
  •  

Question

I have a TreeViewItem where I am using a TextBlock for the Header property and a custom class as the Tag property. How do I go about creating a copy of the TreeViewItem? I've tried serializing it, but it keeps going into an infinite loop, creates a Stack OverFlow Exception, when it tries to serialize the TreeViewItem, but I can't find out where.

This is the custom class I am using as a Tag property for my TreeViewItem

 [Serializable]
 [XmlRoot(ElementName="TVITagProperty")]
 public class TVITagProperty {
      #region Members
      /// <summary>
      /// Tree Type
      /// </summary>
      public enum TreeType {
           User = 1,
           Other = 2,
      }

      /// <summary>
      /// Tag Property Type
      /// </summary>
      public enum TagType {
           Entity = 1,
           User = 2,
      };
      #endregion

      #region C'tor
      /// <summary>
      /// Public parameterless constructor
      /// </summary>
      public TVITagProperty() { }

      /// <summary>
      /// Create a TreeViewItem Tag Property
      /// </summary>
      /// <param name="type">Type of Tag Property</param>
      /// <param name="value">Value of Tag Property</param>
      public TVITagProperty(TreeType treeType, TagType tagType, string value) {
           ViewType = treeType;
           PropertyType = tagType;
           PropertyValue = value;
           PropertyDirectory = false;
      }

      /// <summary>
      /// Create a TreeViewItem Tag Property
      /// </summary>
      /// <param name="type">Type of Tag Property</param>
      /// <param name="value">Value of Tag Property</param>
      public TVITagProperty(TagType type, long? value) {
           PropertyType = type;
           PropertyValue = value.ToString();
      }
      #endregion

      #region Methods
      /// <summary>
      /// Overloaded Equals method, compares one TVI Tag Property Property Type and Value
      /// </summary>
      /// <param name="obj"></param>
      /// <returns></returns>
      public bool Equals(TVITagProperty obj) {
           if(obj != null) {
                if(obj.PropertyDirectory == true) {
                     if(this.ViewType == obj.ViewType &&
                          this.PropertyType == obj.PropertyType) {
                          return true;
                     }
                }
                else if(this.ViewType == obj.ViewType &&
                     this.PropertyType == obj.PropertyType &&
                     this.PropertyValue.Equals(obj.PropertyValue)) {
                     return true;
                }
           }
           return false;
      }

      /// <summary>
      /// Overrides ToString() and returns Property value
      /// </summary>
      /// <returns></returns>
      public override string ToString() {
           return this.PropertyValue;
      }

      /// <summary>
      /// Returns the Property value as a long
      /// </summary>
      /// <returns></returns>
      public long ToLong() {
           return long.Parse(this.PropertyValue);
      }
      #endregion

      #region Properties
      /// <summary>
      /// Represents the type of TreeView used in the View
      /// </summary>
      [XmlAttribute]
      public TreeType ViewType { get; set; }
      /// <summary>
      /// The type of Property Tag
      /// </summary>
      [XmlAttribute]
      public TagType PropertyType { get; set; }
      /// <summary>
      /// The value of Property Tag
      /// </summary>
      [XmlAttribute]
      public string PropertyValue { get; set; }
      /// <summary>
      /// Defines whether the TVI is an object or directory
      /// </summary>
      [XmlAttribute]
      public bool PropertyDirectory { get; set; }
      #endregion
 }
Was it helpful?

Solution

Creating a copy of a wpf TreeViewItem seems like the wrong approach - why do you want to do that?

A better way is to not generate any treeviewitems yourself but let wpf handle it via a hierachical template and itemsource -then you can make copies of your objects in your itemssource and wpf will render them for you.

see for example this:

WPF: Correctly storing an object in a TreeViewItem

OTHER TIPS

There is a good deep clone object on codeproject here

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;     

/// <summary>
/// Provides a method for performing a deep copy of an object.
/// Binary Serialization is used to perform the copy.
/// </summary>
public static class ObjectCopier
{
 /// <summary>
 /// Perform a deep Copy of the object.
 /// </summary>
 /// <typeparam name="T">The type of object being copied.</typeparam>
 /// <param name="source">The object instance to copy.</param>
 /// <returns>The copied object.</returns>
 public static T Clone<T>(T source)
 {
  if (!typeof(T).IsSerializable)
  {
    throw new ArgumentException("The type must be serializable.", "source");
  }

  // Don't serialize a null object, simply return the default for that object
  if (Object.ReferenceEquals(source, null))
  {
    return default(T);
  }

  IFormatter formatter = new BinaryFormatter();
  Stream stream = new MemoryStream();
  using (stream)
  {
    formatter.Serialize(stream, source);
    stream.Seek(0, SeekOrigin.Begin);
    return (T)formatter.Deserialize(stream);
  }
 }
}

More references and discussion posted here

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top