TreeView到Json C#

TreeView到Json C#,c#,winforms,C#,Winforms,您好,我有一个项目,其中一个Json数据反序列化为一个对象类,然后将对象类转换为treeview,编辑树视图节点,我需要将treeview转换为Json 对象类 public class CategoryLink { public string position { get; set; } public string category_id { get; set; } } public class StockItem {

您好,我有一个项目,其中一个Json数据反序列化为一个对象类,然后将对象类转换为treeview,编辑树视图节点,我需要将treeview转换为Json

对象类

public class CategoryLink
    {
        public string position { get; set; }
        public string category_id { get; set; }
    }

    public class StockItem
    {
        public string item_id { get; set; }
        public string product_id { get; set; }
        public string stock_id { get; set; }
        public string qty { get; set; }
        public bool is_in_stock { get; set; }
        public bool is_qty_decimal { get; set; }
        public bool show_default_notification_message { get; set; }
        public bool use_config_min_qty { get; set; }
        public string min_qty { get; set; }
        public string use_config_min_sale_qty { get; set; }
        public string min_sale_qty { get; set; }
        public bool use_config_max_sale_qty { get; set; }
        public string max_sale_qty { get; set; }
        public bool use_config_backorders { get; set; }
        public string backorders { get; set; }
        public bool use_config_notify_stock_qty { get; set; }
        public string notify_stock_qty { get; set; }
        public bool use_config_qty_increments { get; set; }
        public string qty_increments { get; set; }
        public bool use_config_enable_qty_inc { get; set; }
        public bool enable_qty_increments { get; set; }
        public bool use_config_manage_stock { get; set; }
        public bool manage_stock { get; set; }
        public object low_stock_date { get; set; }
        public bool is_decimal_divided { get; set; }
        public string stock_status_changed_auto { get; set; }
    }

    public class ExtensionAttributes
    {
        public IList<string> website_ids { get; set; }
        public IList<CategoryLink> category_links { get; set; }
        public StockItem stock_item { get; set; }
    }

    public class ProductLink
    {
        public string sku { get; set; }
        public string link_type { get; set; }
        public string linked_product_sku { get; set; }
        public string linked_product_type { get; set; }
        public string position { get; set; }
    }

    public class MediaGalleryEntry
    {
        public string id { get; set; }
        public string media_type { get; set; }
        public string label { get; set; }
        public string position { get; set; }
        public bool disabled { get; set; }
        public IList<string> types { get; set; }
        public string file { get; set; }
    }

    public class CustomAttribute
    {
        public string attribute_code { get; set; }
        public object value { get; set; }
    }

    public class Product
    {
        public string id { get; set; }
        public string sku { get; set; }
        public string name { get; set; }
        public string attribute_set_id { get; set; }
        public string price { get; set; }
        public string status { get; set; }
        public string visibility { get; set; }
        public string type_id { get; set; }
        public string created_at { get; set; }
        public string updated_at { get; set; }
        public string weight { get; set; }
        public ExtensionAttributes extension_attributes { get; set; }
        public IList<ProductLink> product_links { get; set; }
        public IList<object> options { get; set; }
        public IList<MediaGalleryEntry> media_gallery_entries { get; set; }
        public IList<object> tier_prices { get; set; }
        public IList<CustomAttribute> custom_attributes { get; set; }
    }

    public class ProductCreateUpdate
    {
        public Product product { get; set; }
        public bool saveOptions { get; set; }
    }

    //GET ALLL PRODUCTS

    public class Item
    {
        public string id { get; set; }
        public string sku { get; set; }
        public string name { get; set; }
        public string attribute_set_id { get; set; }
        public string price { get; set; }
        public string status { get; set; }
        public string visibility { get; set; }
        public string type_id { get; set; }
        public string created_at { get; set; }
        public string updated_at { get; set; }
        public string weight { get; set; }
        public ExtensionAttributes extension_attributes { get; set; }
        public IList<ProductLink> product_links { get; set; }
        public IList<object> options { get; set; }
        public IList<MediaGalleryEntry> media_gallery_entries { get; set; }
        public IList<object> tier_prices { get; set; }
        public IList<CustomAttribute> custom_attributes { get; set; }
    }

    public class SearchCriteria
    {
        public IList<object> filter_groups { get; set; }
        public string page_size { get; set; }
    }

    public class ProductGetAll
    {
        public IList<Item> items { get; set; }
        public SearchCriteria search_criteria { get; set; }
        public string total_count { get; set; }
    }
公共类类别链接
{
公共字符串位置{get;set;}
公共字符串类别_id{get;set;}
}
公共类库存项目
{
公共字符串项_id{get;set;}
公共字符串乘积_id{get;set;}
公共字符串stock_id{get;set;}
公共字符串数量{get;set;}
公共布尔值是{get;set;}
公共布尔是_数量_十进制{get;set;}
公共bool show_default_notification_message{get;set;}
公共bool使用配置最小数量{get;set;}
公共字符串最小数量{get;set;}
公共字符串use_config_min_sale_qty{get;set;}
公共字符串最小销售数量{get;set;}
公共bool use_config_max_sale_qty{get;set;}
公共字符串最大销售数量{get;set;}
公共bool使用_config_backorders{get;set;}
公共字符串延期交货{get;set;}
公共bool使用配置通知库存数量{get;set;}
公共字符串notify_stock_qty{get;set;}
公共bool使用配置数量增量{get;set;}
公共字符串数量_增量{get;set;}
公共bool使用配置启用数量inc{get;set;}
公共bool启用数量增量{get;set;}
公共bool use_config_manage_stock{get;set;}
公共bool manage_stock{get;set;}
公共对象低库存日期{get;set;}
公共布尔是_decimal_divided{get;set;}
公共字符串stock\u status\u changed\u auto{get;set;}
}
公共类扩展属性
{
公共IList网站_id{get;set;}
公共IList类别_链接{get;set;}
public StockItem stock_item{get;set;}
}
公共类ProductLink
{
公共字符串sku{get;set;}
公共字符串链接类型{get;set;}
公共字符串链接的\u产品\u sku{get;set;}
公共字符串链接的_产品_类型{get;set;}
公共字符串位置{get;set;}
}
公共类MediaGalleryEntry
{
公共字符串id{get;set;}
公共字符串媒体类型{get;set;}
公共字符串标签{get;set;}
公共字符串位置{get;set;}
公共bool已禁用{get;set;}
公共IList类型{get;set;}
公共字符串文件{get;set;}
}
公共类CustomAttribute
{
公共字符串属性_代码{get;set;}
公共对象值{get;set;}
}
公共类产品
{
公共字符串id{get;set;}
公共字符串sku{get;set;}
公共字符串名称{get;set;}
公共字符串属性_set_id{get;set;}
公共字符串price{get;set;}
公共字符串状态{get;set;}
公共字符串可见性{get;set;}
公共字符串类型_id{get;set;}
在{get;set;}处创建的公共字符串
在{get;set;}处更新了公共字符串
公共字符串权重{get;set;}
公共扩展属性扩展属性{get;set;}
公共IList产品链接{get;set;}
公共IList选项{get;set;}
公共IList媒体库项目{get;set;}
公共IList tier_价格{get;set;}
公共IList自定义_属性{get;set;}
}
公共类ProductCreateUpdate
{
公共产品产品{get;set;}
公共bool保存选项{get;set;}
}
//获取所有产品
公共类项目
{
公共字符串id{get;set;}
公共字符串sku{get;set;}
公共字符串名称{get;set;}
公共字符串属性_set_id{get;set;}
公共字符串price{get;set;}
公共字符串状态{get;set;}
公共字符串可见性{get;set;}
公共字符串类型_id{get;set;}
在{get;set;}处创建的公共字符串
在{get;set;}处更新了公共字符串
公共字符串权重{get;set;}
公共扩展属性扩展属性{get;set;}
公共IList产品链接{get;set;}
公共IList选项{get;set;}
公共IList媒体库项目{get;set;}
公共IList tier_价格{get;set;}
公共IList自定义_属性{get;set;}
}
公共类搜索标准
{
公共IList筛选器_组{get;set;}
公共字符串页大小{get;set;}
}
公共类ProductGetAll
{
公共IList项{get;set;}
公共搜索条件搜索_条件{get;set;}
公共字符串总计数{get;set;}
}
将反序列化对象分类到Treeview

public static class ObjectToTreeView
    {
        private sealed class IndexContainer
        {
            private int _n;
            public int Inc() => _n++;
        }

        private static void FillTreeView(TreeNode node, JToken tok, Stack<IndexContainer> s)
        {
            if (tok.Type == JTokenType.Object)
            {
                TreeNode n = node;
                if (tok.Parent != null)
                {
                    if (tok.Parent.Type == JTokenType.Property)
                    {
                        n = node.Nodes.Add($"{((JProperty)tok.Parent).Name} <{tok.Type.ToString()}>");
                    }
                    else
                    {
                        n = node.Nodes.Add($"[{s.Peek().Inc()}] <{tok.Type.ToString()}>");
                    }
                }
                s.Push(new IndexContainer());
                foreach (var p in tok.Children<JProperty>())
                {
                    FillTreeView(n, p.Value, s);
                }
                s.Pop();
            }
            else if (tok.Type == JTokenType.Array)
            {
                TreeNode n = node;
                if (tok.Parent != null)
                {
                    if (tok.Parent.Type == JTokenType.Property)
                    {
                        n = node.Nodes.Add($"{((JProperty)tok.Parent).Name} <{tok.Type.ToString()}>");
                    }
                    else
                    {
                        n = node.Nodes.Add($"[{s.Peek().Inc()}] <{tok.Type.ToString()}>");
                    }
                }
                s.Push(new IndexContainer());
                foreach (var p in tok)
                {
                    FillTreeView(n, p, s);
                }
                s.Pop();
            }
            else
            {
                var name = string.Empty;
                var value = JsonConvert.SerializeObject(((JValue)tok).Value);

                if (tok.Parent.Type == JTokenType.Property)
                {
                    name = $"{((JProperty)tok.Parent).Name} : {value}";
                }
                else
                {
                    name = $"[{s.Peek().Inc()}] : {value}";
                }

                node.Nodes.Add(name);
            }
        }

        public static void SetObjectAsJson<T>(this TreeView tv, T obj)
        {
            tv.BeginUpdate();
            try
            {
                tv.Nodes.Clear();

                var s = new Stack<IndexContainer>();
                s.Push(new IndexContainer());
                FillTreeView(tv.Nodes.Add("ROOT"), JsonConvert.DeserializeObject<JToken>(JsonConvert.SerializeObject(obj)), s);
                s.Pop();
            }
            finally
            {
                tv.EndUpdate();
            }
        }
    }
公共静态类ObjectToTreeView
{
私有密封类索引容器
{
私人国际;
public int Inc()=>\u n++;
}
私有静态void FillTreeView(TreeNode节点、JToken tok、堆栈s)
{
if(tok.Type==JTokenType.Object)
{
树节点n=节点;
如果(tok.Parent!=null)
{
if(tok.Parent.Type==JTokenType.Property)
{
n=node.Nodes.Add($”{((JProperty)tok.Parent.Name});
}
其他的
{
n=node.Nodes.Add($“[{s.Peek().Inc()}]”);
}
}
s、 推送(新的IndexContainer());
foreach(tok.Children()中的var p)
{
FillTreeView(n,p.值,s);
}
s、 Pop();
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Windows.Forms;

public class JsonTreeView : TreeView
{
    private JToken _object;

    private event EventHandler OnJsonObjectChanged;

    private static class ObjectToTreeView
    {
        public sealed class IndexContainer
        {
            private int _n;
            public int Inc() => _n++;
        }

        public static void FillTreeView(TreeNode node, JToken tok, Stack<IndexContainer> s)
        {
            if (tok.Type == JTokenType.Object)
            {
                TreeNode n = node;
                if (tok.Parent != null)
                {
                    if (tok.Parent.Type == JTokenType.Property)
                    {
                        n = node.Nodes.Add($"{((JProperty)tok.Parent).Name} <{tok.Type}>");
                    }
                    else
                    {
                        n = node.Nodes.Add($"[{s.Peek().Inc()}] <{tok.Type}>");
                    }
                }
                s.Push(new IndexContainer());
                foreach (var p in tok.Children<JProperty>())
                {
                    FillTreeView(n, p.Value, s);
                }
                s.Pop();
            }
            else if (tok.Type == JTokenType.Array)
            {
                TreeNode n = node;
                if (tok.Parent != null)
                {
                    if (tok.Parent.Type == JTokenType.Property)
                    {
                        n = node.Nodes.Add($"{((JProperty)tok.Parent).Name} <{tok.Type}>");
                    }
                    else
                    {
                        n = node.Nodes.Add($"[{s.Peek().Inc()}] <{tok.Type}>");
                    }
                }
                s.Push(new IndexContainer());
                foreach (var p in tok)
                {
                    FillTreeView(n, p, s);
                }
                s.Pop();
            }
            else
            {
                var value = JsonConvert.SerializeObject(((JValue)tok).Value);

                string name;
                if (tok.Parent.Type == JTokenType.Property)
                {
                    name = $"{((JProperty)tok.Parent).Name} : {value}";
                }
                else
                {
                    name = $"[{s.Peek().Inc()}] : {value}";
                }
                // NEW: store a reference to this token
                node.Nodes.Add(name).Tag = tok;
            }
        }
    }

    public JsonTreeView()
    {
        LabelEdit = true;
        BeforeLabelEdit += OnBeforeLabelEdit;
        AfterLabelEdit += OnAfterLabelEdit;
    }

    private void OnBeforeLabelEdit(object sender, NodeLabelEditEventArgs e)
    {
        e.CancelEdit = e.Node.Tag == null;
    }

    private void OnAfterLabelEdit(object sender, NodeLabelEditEventArgs e)
    {
        if (string.IsNullOrEmpty(e.Label)) { return; }

        var originalToken = (JToken)e.Node.Tag;
        var newText = e.Label;

        // must have separator
        var indSplit = newText.IndexOf(" :");
        if (indSplit == -1)
        {
            e.CancelEdit = true;
            return;
        }

        // front must match original name
        if (!newText.StartsWith(e.Node.Text.Substring(0, indSplit + 2)))
        {
            e.CancelEdit = true;
            return;
        }

        // new text should have value
        var newTextValue = newText.Substring(indSplit + 2).Trim();
        if (string.IsNullOrWhiteSpace(newTextValue))
        {
            e.CancelEdit = true;
            return;
        }

        // let newtonsoft create a new value based on user entry
        JValue newValue;
        try
        {
            newValue = JsonConvert.DeserializeObject<JValue>(newTextValue);
        }
        catch (JsonReaderException)
        {
            e.CancelEdit = true;
            return;
        }

        // types must match (unless it's null)
        {
            var origType = ((JValue)originalToken).Type;
            if ((origType == JTokenType.Null) || (newValue.Type == JTokenType.Null))
            {
                // we are going to skip this conversion because there is no type
            }
            else
            {
                if(origType != newValue.Type)
                {
                    e.CancelEdit = true;
                    return;
                }
            }
        }

        // set it
        ((JValue)originalToken).Value = newValue?.Value;

        // reset the value incase the value text changed
        e.CancelEdit = true;
        e.Node.Text = $"{e.Node.Text.Substring(0, indSplit + 3)}" +
            $"{JsonConvert.SerializeObject(((JValue)originalToken).Value)}";

        // fire off notification
        OnJsonObjectChanged?.Invoke(this, EventArgs.Empty);
    }

    public void SetJsonObject(object obj)
    {
        BeginUpdate();
        try
        {
            Nodes.Clear();

            var s = new Stack<ObjectToTreeView.IndexContainer>();
            s.Push(new ObjectToTreeView.IndexContainer());
            _object = JsonConvert.DeserializeObject<JToken>(JsonConvert.SerializeObject(obj));
            ObjectToTreeView.FillTreeView(Nodes.Add("ROOT"), _object, s);
            s.Pop();
        }
        finally
        {
            EndUpdate();
        }
    }

    public TResult GetJsonObject<TResult>()
    {
        return JsonConvert.DeserializeObject<TResult>(JsonConvert.SerializeObject(_object));
    }
}
if (jsonEditProduct.SelectedNode.Text.Contains(":"))
                {
                    string[] nameField = jsonEditProduct.SelectedNode.Text.Split(new[] { ':' }, 2);
                    jsonEditProduct.SelectedNode.Text = nameField[0] + ":" + " \"" + fieldJsonTextBox.Text + "\"";
                }
using Magento;
using Magento.Products;
using System;
using System.Drawing;
using System.Windows.Forms;

namespace MagentoAPI
{
    public partial class MainForm : Form
    {
        private WaitForm _waitForm;
        private MagentoMain magento;
        private JsonTreeView jsonEditProduct = new JsonTreeView();
        ProductGetAll productsGetAll;

        public MainForm(MagentoMain magento)
        {
            InitializeComponent();
            LoadIconsTabControl();
            panel11.Controls.Add(jsonEditProduct);
            jsonEditProduct.Dock = DockStyle.Fill;
            jsonEditProduct.AfterSelect += new TreeViewEventHandler(jsonEditProduct_AfterSelect);
            this.magento = magento;
        }

        internal void LoadIconsTabControl()
        {
            ImageList iconsList = new ImageList();
            iconsList.TransparentColor = Color.Orange;
            iconsList.ColorDepth = ColorDepth.Depth32Bit;
            iconsList.ImageSize = new Size(48, 48);
            var icon = Properties.Resources.productEdit;
            iconsList.Images.Add(icon);
            icon = Properties.Resources.productAdd;
            iconsList.Images.Add(icon);
            tabControl.ImageList = iconsList;
            tabControl.TabPages[0].ImageIndex = 0;
            tabControl.TabPages[1].ImageIndex = 1;
        }

        protected void ShowWaitForm(string message)
        {
            // don't display more than one wait form at a time
            if (_waitForm != null && !_waitForm.IsDisposed)
            {
                return;
            }

            _waitForm = new WaitForm();
            _waitForm.SetMessage(message); // "Loading data. Please wait..."
            _waitForm.TopMost = true;
            _waitForm.StartPosition = FormStartPosition.CenterScreen;
            _waitForm.Show();
            _waitForm.Refresh();

            // force the wait window to display for at least 700ms so it doesn't just flash on the screen
            System.Threading.Thread.Sleep(700);
            Application.Idle += OnLoaded;
        }

        private void OnLoaded(object sender, EventArgs e)
        {
            Application.Idle -= OnLoaded;
            _waitForm.Close();
        }

        private void ProductsGetAllButton_Click(object sender, EventArgs e)
        {
            ShowWaitForm("Espere descargando productos...");
            productsGetAll = magento.GetAllProdcuts();
            skuListBox.Items.Clear();
            foreach (Item item in productsGetAll.items)
            {
                skuListBox.Items.Add(item.sku);
            }
            
        }

        private void skuListBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            foreach (Item item in productsGetAll.items)
            {
                if (item.sku == skuListBox.SelectedItem.ToString())
                {
                    jsonEditProduct.SetJsonObject(item);
                }
            }
        }

        private void jsonEditProduct_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (jsonEditProduct.SelectedNode.Text.Contains(":"))
            {
                string[] nameField = jsonEditProduct.SelectedNode.Text.Split(new[] { ':' }, 2);
                nameJsonTextBox.Text = nameField[0].Trim(' ').Trim('"');
                fieldJsonTextBox.Text = nameField[1].Trim(' ').Trim('"');
            }
        }

        private void fieldJsonTextBox_TextChanged(object sender, EventArgs e)
        {
            if (jsonEditProduct.SelectedNode.Text.Contains(":"))
            {
                string[] nameField = jsonEditProduct.SelectedNode.Text.Split(new[] { ':' }, 2);
                jsonEditProduct.SelectedNode.Text = nameField[0] + ":" + " \"" + fieldJsonTextBox.Text + "\"";
            }
        }

        private void updateProductButton_Click(object sender, EventArgs e)
        {
            Item item = jsonEditProduct.GetJsonObject<Item>();
            //UPDATE NOT READY
        }
    }
}