【问题标题】:How do I copy a TreeViewItem onto another that is using an object as a tag and header?如何将 TreeViewItem 复制到另一个使用对象作为标签和标题的对象上?
【发布时间】:2012-09-24 18:47:38
【问题描述】:

我有一个 TreeViewItem,我在其中使用 TextBlock 作为 Header 属性,并使用自定义类作为 Tag 属性。如何创建 TreeViewItem 的副本?我试过序列化它,但它一直进入一个无限循环,当它试图序列化 TreeViewItem 时,会创建一个 Stack OverFlow 异常,但我找不到在哪里。

这是我用作 TreeViewItem 的 Tag 属性的自定义类

 [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
 }

【问题讨论】:

    标签: c# wpf cloning


    【解决方案1】:

    创建 wpf TreeViewItem 的副本似乎是错误的方法 - 为什么要这样做?

    更好的方法是不自己生成任何树视图项,而是让 wpf 通过分层模板和 itemsource 处理它 - 然后您可以在 itemssource 中复制对象,wpf 将为您呈现它们。

    例如看这个:

    WPF: Correctly storing an object in a TreeViewItem

    【讨论】:

    • 命令绑定、静态类绑定上下文菜单和拖放怎么样?
    • 你的意思是做一个深拷贝?我发现通过 mvvm 使用命令绑定,使用自定义命令类,是一个好方法。来自静态属性的上下文菜单,嗯,它可以工作,但它不是最好的:) 通过拖放,您可以获得一个被拖动的控件实例 - 如果它是自动创建的树视图项,您可以从 DataContext 获取它的数据财产做某事。尽可能将 gui 与逻辑分开通常是一个好主意。通常不需要序列化控件,但如果你真的想要,请查看 xamlreader/writer :)
    【解决方案2】:

    codeprojecthere上有一个很好的深度克隆对象

    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);
      }
     }
    }
    

    更多参考资料和讨论张贴here

    【讨论】:

      猜你喜欢
      • 2022-11-25
      • 1970-01-01
      • 1970-01-01
      • 2017-01-23
      • 1970-01-01
      • 2017-05-08
      • 2011-02-07
      • 2016-04-04
      • 1970-01-01
      相关资源
      最近更新 更多