public override void Create(VisualElement root)
        {
            var asset             = ScriptableObject.CreateInstance <SampleAsset>();
            var obj               = new SerializedObject(asset);
            var typedPrimitives   = new List <int>();
            var typedClasses      = new List <SampleItemBool>();
            var typedReferences   = new List <ISampleItem>();
            var genericPrimitives = new List <int>();
            var genericClasses    = new List <SampleItemBool>();
            var genericReferences = new List <ISampleItem>();

            var proxies = new List <ProxySelect>
            {
                new ProxySelect("Typed Primitive", new ListProxy <int>(typedPrimitives, CreateInt), null, false, typedPrimitives),
                new ProxySelect("Typed Class", new ListProxy <SampleItemBool>(typedClasses, CreateSampleItemBool), typeof(SampleItemBool), false, typedClasses),
                new ProxySelect("Typed Reference", new ListProxy <ISampleItem>(typedReferences, CreateSampleItem), typeof(ISampleItem), true, typedReferences),
                new ProxySelect("Generic Primitive", new ListProxy(genericPrimitives, CreateInt), typeof(int), false, genericPrimitives),
                new ProxySelect("Generic Class", new ListProxy(genericClasses, CreateSampleItemBool), typeof(SampleItemBool), false, genericClasses),
                new ProxySelect("Generic Reference", new ListProxy(genericReferences, CreateSampleItem), typeof(ISampleItem), true, genericReferences),
                new ProxySelect("Property Primitive", CreatePropertyProxy(obj, nameof(SampleAsset.Primitives)), null, false, asset.Primitives),
                new ProxySelect("Property Class", CreatePropertyProxy(obj, nameof(SampleAsset.Classes)), null, false, asset.Classes),
                new ProxySelect("Property Reference", CreatePropertyProxy(obj, nameof(SampleAsset.References)), typeof(ISampleItem), true, asset.References),
                new ProxySelect("None", null, null, false, null)
            };

            var startingProxy = 0;
            var list          = new ListField();

            list.Label = "Sample List";
            list.SetProxy(proxies[startingProxy].Proxy, proxies[startingProxy].ItemType, proxies[startingProxy].AllowDerived);
            root.Add(list);

            var proxyPopup = new UnityEditor.UIElements.PopupField <ProxySelect>("Item Type", proxies, startingProxy, proxy => proxy.Name, proxy => proxy.Name);

            proxyPopup.RegisterValueChangedCallback(e => list.SetProxy(e.newValue.Proxy, e.newValue.ItemType, e.newValue.AllowDerived));
            root.Add(proxyPopup);

            var allowAddToggle = new Toggle("Allow Add");

            allowAddToggle.value = list.AllowAdd;
            allowAddToggle.RegisterValueChangedCallback(e => list.AllowAdd = e.newValue);
            root.Add(allowAddToggle);

            var allowRemoveToggle = new Toggle("Allow Remove");

            allowRemoveToggle.value = list.AllowRemove;
            allowRemoveToggle.RegisterValueChangedCallback(e => list.AllowRemove = e.newValue);
            root.Add(allowRemoveToggle);

            var allowReorderToggle = new Toggle("Allow Reorder");

            allowReorderToggle.value = list.AllowReorder;
            allowReorderToggle.RegisterValueChangedCallback(e => list.AllowReorder = e.newValue);
            root.Add(allowReorderToggle);

            var emptyLabelText = new TextField("Empty Label");

            emptyLabelText.value = list.EmptyLabel;
            emptyLabelText.RegisterValueChangedCallback(e => list.EmptyLabel = e.newValue);
            root.Add(emptyLabelText);

            var emptyTooltipText = new TextField("Empty Tooltip");

            emptyTooltipText.value = list.EmptyTooltip;
            emptyTooltipText.RegisterValueChangedCallback(e => list.EmptyTooltip = e.newValue);
            root.Add(emptyTooltipText);

            var addTooltipText = new TextField("Add Tooltip");

            addTooltipText.value = list.AddTooltip;
            addTooltipText.RegisterValueChangedCallback(e => list.AddTooltip = e.newValue);
            root.Add(addTooltipText);

            var removeTooltipText = new TextField("Remove Tooltip");

            removeTooltipText.value = list.RemoveTooltip;
            removeTooltipText.RegisterValueChangedCallback(e => list.RemoveTooltip = e.newValue);
            root.Add(removeTooltipText);

            var reorderTooltipText = new TextField("Reorder Tooltip");

            reorderTooltipText.value = list.ReorderTooltip;
            reorderTooltipText.RegisterValueChangedCallback(e => list.ReorderTooltip = e.newValue);
            root.Add(reorderTooltipText);

            var printButton = new Button(() => Print(proxies[proxyPopup.index].List));

            printButton.text = "Log List Contents";
            root.Add(printButton);
        }
        private void SetupUI()
        {
            var styleSheet = AssetDatabase.LoadAssetAtPath <StyleSheet>($"{Utils.packageFolderName}/Editor/StyleSheets/PerformanceTrackerWindow.uss");

            rootVisualElement.styleSheets.Add(styleSheet);

            m_RefreshFromSearch = Delayer.Throttle(RefreshFromSearch);

            var toolbar = new UnityEditor.UIElements.Toolbar();

            toolbar.AddToClassList("perf-toolbar");
            toolbar.style.height = PtStyles.itemHeight;

            var searchBox = new VisualElement();

            searchBox.AddToClassList("perf-search-box");
            AddSelectorLabel(toolbar, "Tracker");
            m_SearchField = new ToolbarSearchField();
            m_SearchField.AddToClassList("perf-search-tracker");
            m_SearchField.value = m_FilterText;
            m_SearchField.RegisterCallback <ChangeEvent <string> >((evt) =>
            {
                m_RefreshFromSearch.Execute(evt.newValue);
            });
            searchBox.Add(m_SearchField);
            toolbar.Add(searchBox);

            var resetAllCountersButton = new Button(ResetAllCounters);

            resetAllCountersButton.text = "Reset all counters";
            resetAllCountersButton.AddToClassList("perf-tracker-toolbar-button");
            toolbar.Add(resetAllCountersButton);

            AddSelectorLabel(toolbar, "Update Speed");
            var choices             = PtModel.RefreshRates.Select(r => r.label).ToList();
            var updateSpeedSelector = new UnityEditor.UIElements.PopupField <string>(choices, 0);

            updateSpeedSelector.value = PtModel.RefreshRates[m_UpdateSpeedIndex].label;
            updateSpeedSelector.AddToClassList("perf-update-speed-selector");
            updateSpeedSelector.RegisterCallback <ChangeEvent <string> >((evt) =>
            {
                m_UpdateSpeedIndex = Array.FindIndex(PtModel.RefreshRates, (r) => r.label == evt.newValue);
                ScheduleNextRefresh();
                SendAnalytics(Analytics.WindowUsageType.ChangeMonitoringSpeed);
            });
            toolbar.Add(updateSpeedSelector);

            AddSelectorLabel(toolbar, "Columns");
            var columnsChoice   = PtModel.ColumnDescriptors.Where(desc => desc.columnsSelectorMaskId > 0).Select(desc => desc.label).ToList();
            var columnsSelector = new MaskField(columnsChoice, m_ShownColumn);

            columnsSelector.RegisterCallback <ChangeEvent <int> >((evt) =>
            {
                m_ShownColumn = evt.newValue;
                CreateHeaders();
                RefreshTrackers();
                SendAnalytics(Analytics.WindowUsageType.ChangeColumnLayout);
            });
            columnsSelector.AddToClassList("perf-columns-selector");
            toolbar.Add(columnsSelector);

            AddSelectorLabel(toolbar, "Sort By");
            m_SortBySelector       = new EnumField(ColumnId.Name);
            m_SortBySelector.value = m_SortBy;
            m_SortBySelector.AddToClassList("perf-sort-by-selector");
            m_SortBySelector.RegisterCallback <ChangeEvent <Enum> >((evt) =>
            {
                ChangeSortOrder((ColumnId)evt.newValue);
                SendAnalytics(Analytics.WindowUsageType.ChangeSortBy);
            });
            toolbar.Add(m_SortBySelector);

            var settingsBtn = new Button(() =>
            {
                SettingsService.OpenUserPreferences(PerformanceTrackerSettings.settingsKey);
                SendAnalytics(Analytics.WindowUsageType.OpenPreferences);
            });

            settingsBtn.style.backgroundImage = Icons.settings;
            settingsBtn.style.width           = PtStyles.itemHeight - 3;
            settingsBtn.style.height          = PtStyles.itemHeight - 3;

            toolbar.Add(settingsBtn);

            rootVisualElement.Add(toolbar);

            // Set List View Header:
            m_HeaderRow = new VisualElement();
            m_HeaderRow.AddToClassList("perf-header-row-container");
            m_HeaderRow.style.flexDirection = FlexDirection.Row;
            rootVisualElement.Add(m_HeaderRow);
            CreateHeaders();

            m_PinnedTrackersView      = new ListView(m_PinnedTrackers, PtStyles.itemHeight, MakeItem, BindPinnedItem);
            m_PinnedTrackersView.name = k_PinnedTrackerList;
            m_PinnedTrackersView.AddToClassList("perf-tracker-list");
            m_PinnedTrackersView.selectionType  = SelectionType.Multiple;
            m_PinnedTrackersView.style.flexGrow = 0;
            m_PinnedTrackersView.Q <VisualElement>(null, "unity-scroll-view__content-viewport").RegisterCallback <GeometryChangedEvent>(SyncHeaderAndListsGeometry);
            rootVisualElement.Add(m_PinnedTrackersView);

            m_TrackersView      = new ListView(m_FilteredTrackers, PtStyles.itemHeight, MakeItem, BindUnpinnedItem);
            m_TrackersView.name = k_TrackerList;
            m_TrackersView.AddToClassList("perf-tracker-list");
            m_TrackersView.selectionType  = SelectionType.Multiple;
            m_TrackersView.style.flexGrow = 1.0f;

            m_TrackersView.Q <VisualElement>(null, "unity-scroll-view__content-viewport").RegisterCallback <GeometryChangedEvent>(SyncHeaderAndListsGeometry);

            rootVisualElement.Add(m_TrackersView);

            m_NeedsUpdate = true;
            ScheduleNextRefresh();
            UpdateTrackers();
        }