Download YamlDotNetTypeConverter.zip, last updated 01/04/2017 (27.73 KB)

Download
  • md5: 66fdcbddcff158af2b4d7d8756150c2a
  • sha1: a31655e072b0d1cebb4a03a51c3780cadaaf3d24
  • sha256: 70865eff552b26245c036320b92b2d2f010b0e62cffb0b7f9b4728e972509a6a
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;

// Using custom type converters with C# and YamlDotNet, part 1
// http://www.cyotek.com/blog/using-custom-type-converters-with-csharp-and-yamldotnet-part-1

// This work is licensed under the Creative Commons Attribution 4.0 International License.
// To view a copy of this license, visit http://creativecommons.org/licenses/by/4.0/.

namespace YamlDotNetTypeConverter
{
  internal class CategoriesTreeView : TreeView
  {
    #region Fields

    private ContentCategoryCollection _categories;

    #endregion

    #region Properties

    [Browsable(false)]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
    public ContentCategoryCollection Categories
    {
      get { return _categories; }
      set
      {
        _categories = value;

        this.Reload();
      }
    }

    [Browsable(false)]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
    public ContentCategory SelectedCategory
    {
      get
      {
        TreeNode node;

        node = this.SelectedNode;

        return node?.Tag as ContentCategory;
      }
    }

    #endregion

    #region Methods

    public TreeNode Add(ContentCategory value)
    {
      TreeNode node;
      TreeNodeCollection nodes;

      node = null;
      nodes = value.Parent != null ? this.GetFolderNode(value.Parent).Nodes : this.Nodes;

      for (int i = 0; i < nodes.Count; i++)
      {
        TreeNode checkNode;

        checkNode = nodes[i];

        if (ReferenceEquals(checkNode.Tag, value))
        {
          node = checkNode;
          break;
        }
      }

      // ReSharper disable once ConvertIfStatementToNullCoalescingExpression
      if (node == null)
      {
        node = this.AddNode(nodes, value);
      }

      return node;
    }

    public TreeNode GetFolderNode(ContentCategory item)
    {
      return this.MatchTag(this.Nodes, item);
    }

    protected override void OnAfterLabelEdit(NodeLabelEditEventArgs e)
    {
      if (!e.CancelEdit)
      {
        ContentCategory item;

        item = this.SelectedCategory;

        if (item != null)
        {
          item.Title = e.Label;
        }
      }

      base.OnAfterLabelEdit(e);
    }

    private TreeNode AddNode(TreeNodeCollection treeNodes, ContentCategory node)
    {
      TreeNode treeNode;

      treeNode = new TreeNode
                 {
                   Text = node.Title,
                   Tag = node
                 };

      if (node.HasCategories)
      {
        this.AddNodes(treeNode.Nodes, node.Categories);
      }

      treeNodes.Add(treeNode);

      return treeNode;
    }

    private void AddNodes(TreeNodeCollection treeNodes, ContentCategoryCollection nodes)
    {
      foreach (ContentCategory node in nodes)
      {
        this.AddNode(treeNodes, node);
      }
    }

    private TreeNode MatchTag(TreeNodeCollection nodes, object tag)
    {
      Queue<TreeNode> pending;
      TreeNode result;

      result = null;

      pending = new Queue<TreeNode>();
      this.QueueNodes(pending, nodes);

      do
      {
        TreeNode check;

        check = pending.Dequeue();

        if (check != null)
        {
          if (ReferenceEquals(tag, check.Tag))
          {
            result = check;
          }
          else
          {
            this.QueueNodes(pending, check.Nodes);
          }
        }
      } while (pending.Count != 0 && result == null);

      return result;
    }

    private void QueueNodes(Queue<TreeNode> pending, TreeNodeCollection nodes)
    {
      for (int i = 0; i < nodes.Count; i++)
      {
        pending.Enqueue(nodes[i]);
      }
    }

    private void Reload()
    {
      TreeNodeCollection nodes;

      nodes = this.Nodes;

      if (_categories != null)
      {
        this.BeginUpdate();
        nodes.Clear();
        this.AddNodes(nodes, _categories);
        this.EndUpdate();
      }
      else
      {
        nodes.Clear();
      }
    }

    #endregion
  }
}

Donate

Donate