private UIElement Visualize(IResultVisualizer resultVisualizer)
        {
            // Create tree and its columns
            TreeListView tree = new TreeListView();

            tree.Columns.Add(new GridViewColumn()
            {
                Header       = "Name",
                CellTemplate = new DataTemplate()
                {
                    VisualTree = CreateStackPanelFactory("Name")
                },
                Width = 200,
            });
            tree.Columns.Add(new GridViewColumn()
            {
                Header       = "Value",
                CellTemplate = new DataTemplate()
                {
                    VisualTree = CreateStackPanelFactory("Value")
                },
                Width = 600,
            });
            tree.Columns.Add(new GridViewColumn()
            {
                Header       = "Type",
                CellTemplate = new DataTemplate()
                {
                    VisualTree = CreateStackPanelFactory("Type")
                },
                Width = 200,
            });

            // Create header row
            TreeViewItem header = new TreeViewItem();

            header.Header = new GridViewHeaderRowPresenter()
            {
                Columns = tree.Columns,
            };
            tree.Items.Add(header);

            // Create result item
            TreeViewItem resultItem = CreateTreeItem(tree, resultVisualizer, 0);

            tree.Items.Add(resultItem);
            resultItem.IsExpanded = true;

            // Initialize tree events
            tree.PreviewMouseWheel += Tree_PreviewMouseWheel;
            tree.PreviewKeyDown    += Tree_PreviewKeyDown;
            tree.LostFocus         += (a, b) =>
            {
                var item = tree.SelectedItem as TreeViewItem;

                if (item != null)
                {
                    item.IsSelected = false;
                }
            };
            tree.GotFocus += (a, b) =>
            {
                var item = tree.SelectedItem as TreeViewItem;

                if (item == null)
                {
                    if (interactiveWindowContent.TraverseDirection.HasValue)
                    {
                        if (interactiveWindowContent.TraverseDirection == FocusNavigationDirection.Next)
                        {
                            item = tree.Items[1] as TreeViewItem;
                        }
                        else
                        {
                            item = tree.Items[tree.Items.Count - 1] as TreeViewItem;
                            while (item.IsExpanded)
                            {
                                item = item.Items[item.Items.Count - 1] as TreeViewItem;
                            }
                        }
                    }
                    else
                    {
                        item = tree.Items[1] as TreeViewItem;
                    }

                    if (item != null)
                    {
                        item.IsSelected = true;
                    }
                }
            };
            dispatcher = tree.Dispatcher;
            return(tree);
        }
        private void TreeViewItem_Expanded(object sender, RoutedEventArgs e)
        {
            try
            {
                TreeViewItem     item   = e.Source as TreeViewItem;
                TreeListView     tree   = null;
                FrameworkElement parent = item?.Parent as FrameworkElement;

                while (tree == null && parent != null)
                {
                    tree   = parent as TreeListView;
                    parent = parent.Parent as FrameworkElement;
                }

                if ((item.Items.Count == 1) && (item.Items[0].ToString() == ExpandingItemText))
                {
                    TreeViewItemTag tag = item.Tag as TreeViewItemTag;

                    System.Threading.Tasks.Task.Run(() =>
                    {
                        IResultVisualizer resultTreeItem         = tag.ResultTreeItem as IResultVisualizer;
                        IEnumerable <IResultVisualizer> children = tag.ResultTreeItem as IEnumerable <IResultVisualizer>;

                        try
                        {
                            if (resultTreeItem != null)
                            {
                                List <Tuple <string, IEnumerable <IResultVisualizer> > > customChildren = new List <Tuple <string, IEnumerable <IResultVisualizer> > >();

                                foreach (Tuple <string, IEnumerable <IResultVisualizer> > customChild in resultTreeItem.Children)
                                {
                                    if (customChild.Item2.Any())
                                    {
                                        if (customChild.Item1 == "[Expanded]")
                                        {
                                            List <IResultVisualizer> cachedItems = customChild.Item2.ToList();

                                            customChildren.Add(Tuple.Create(customChild.Item1, (IEnumerable <IResultVisualizer>)cachedItems));
                                            foreach (IResultVisualizer child in cachedItems)
                                            {
                                                child.Initialize();
                                            }
                                        }
                                        else
                                        {
                                            customChildren.Add(customChild);
                                        }
                                    }
                                }

                                item.Dispatcher.InvokeAsync(() =>
                                {
                                    try
                                    {
                                        int level = tag.Level;

                                        item.Items.Clear();
                                        foreach (Tuple <string, IEnumerable <IResultVisualizer> > customChild in customChildren)
                                        {
                                            if (customChild.Item1 == "[Expanded]")
                                            {
                                                foreach (IResultVisualizer child in customChild.Item2)
                                                {
                                                    item.Items.Add(CreateTreeItem(tree, child, level + 1));
                                                }
                                            }
                                            else
                                            {
                                                TreeViewItem customItem = CreateTreeItem(tree, customChild.Item1, CompletionData.GetImage(CompletionDataType.Namespace), level + 1, nameItalic: true);

                                                customItem.Tag = new TreeViewItemTag()
                                                {
                                                    Level          = level + 1,
                                                    ResultTreeItem = customChild.Item2,
                                                };
                                                customItem.Items.Add(ExpandingItemText);
                                                customItem.Expanded += TreeViewItem_Expanded;
                                                item.Items.Add(customItem);
                                            }
                                        }
                                    }
                                    catch (Exception ex3)
                                    {
                                        MessageBox.Show(ex3.ToString());
                                    }
                                });
                            }
                            else if (children != null)
                            {
                                List <IResultVisualizer> cachedItems = children.ToList();

                                foreach (IResultVisualizer child in children)
                                {
                                    child.Initialize();
                                }

                                item.Dispatcher.InvokeAsync(() =>
                                {
                                    try
                                    {
                                        int level = tag.Level;

                                        item.Items.Clear();
                                        foreach (IResultVisualizer child in cachedItems)
                                        {
                                            item.Items.Add(CreateTreeItem(tree, child, level + 1));
                                        }
                                    }
                                    catch (Exception ex3)
                                    {
                                        MessageBox.Show(ex3.ToString());
                                    }
                                });
                            }
                        }
                        catch (Exception ex2)
                        {
                            MessageBox.Show(ex2.ToString());
                        }
                    });
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
        private TreeViewItem CreateTreeItem(TreeListView tree, string name, ImageSource imageSource, int level, UIElement value = null, string typeString = null, bool nameItalic = false)
        {
            TreeViewItem         item          = new TreeViewItem();
            bool                 alreadyLoaded = false;
            GridViewRowPresenter rowPresenter  = new GridViewRowPresenter()
            {
                Columns = tree.Columns,
                Content = level,
            };

            item.Header  = rowPresenter;
            item.Loaded += (sender, e) =>
            {
                if (alreadyLoaded)
                {
                    return;
                }
                alreadyLoaded = true;

                FrameworkElement expander        = item.Template.FindName("Expander", item) as FrameworkElement;
                StackPanel       nameStackPanel  = FindVisualChild <StackPanel>(rowPresenter, "Name");
                StackPanel       valueStackPanel = FindVisualChild <StackPanel>(rowPresenter, "Value");
                StackPanel       typeStackPanel  = FindVisualChild <StackPanel>(rowPresenter, "Type");

                if (expander != null && nameStackPanel != null)
                {
                    Panel expanderParent = expander.Parent as Panel;

                    if (expanderParent != null)
                    {
                        if (level > 0)
                        {
                            expanderParent.Margin = new Thickness(-19, 0, 0, 0);
                            nameStackPanel.Margin = new Thickness(10 * (level - 1), 0, 0, 0);
                        }
                        else
                        {
                            nameStackPanel.Margin = new Thickness(-19, 0, 0, 0);
                        }
                        nameStackPanel.Orientation = Orientation.Horizontal;
                        expanderParent.Children.Remove(expander);
                        nameStackPanel.Children.Add(expander);
                        nameStackPanel.Children.Add(CreateTextWithIcon(name, imageSource, italic: nameItalic));
                    }
                }
                if (valueStackPanel != null && value != null)
                {
                    valueStackPanel.Orientation = Orientation.Horizontal;
                    valueStackPanel.Children.Add(value);
                }
                if (typeStackPanel != null && typeString != null)
                {
                    typeStackPanel.Orientation = Orientation.Horizontal;
                    typeStackPanel.Children.Add(new TextBlock()
                    {
                        Text = typeString,
                    });
                }
            };
            return(item);
        }