public TreeItem FindStrategyNearItem(TreeItem treeItem)
        {
            if (treeItem == null)
            {
                return null;
            }

            if (treeItem is LogicalTreeItem && SearchStrategy == SearchStrategy.VisualTree)
            {
                return VisualTreeItem.FindVisualTreeItem(treeItem.Instance);
            }

            if (treeItem is VisualTreeItem && SearchStrategy == SearchStrategy.LogicalTree)
            {
                var logicalItem = LogicalTreeItem.FindLogicalTreeItem(treeItem.Instance);
                while (logicalItem == null)
                {
                    treeItem = treeItem.Parent;
                    logicalItem = LogicalTreeItem.FindLogicalTreeItem(treeItem.Instance);
                }
                treeItem = logicalItem;
            }

            return treeItem;
        }
        public void UpdateRoutedEvents(TreeItem treeItem)
        {
            _eventItems.Clear();
            OnEventsChanged();

            foreach (var routedEvent in RoutedEvents)
            {
                routedEvent.Dispose();
            }

            RoutedEvents.Clear();

            if (treeItem != null )
            {
                var fe = treeItem.Instance as FrameworkElement;
                if (fe != null)
                {
                    var routedEvents = EventManager.GetRoutedEvents();
                    if (routedEvents != null)
                    {
                        foreach (RoutedEvent routedEvent in routedEvents)
                        {
                            RoutedEvents.Add(new RoutedEventHandler(routedEvent, fe, AddEvent));
                        }
                    }
                }
            }

            OnRoutedEventsChanged();
        }
 private static bool IsValidSource(TreeItem item)
 {
     if (item == null)
         return false;
     return item.Instance is Window ||
            item.Instance is UserControl;
 }
示例#4
0
        protected TreeItem(object instance, TreeItem parent, TreeModel model, int level)
        {
            _instance = instance;
            _parent = parent;
            Model = model;
            Level = level;

            var frameworkElement = instance as FrameworkElement;
            if (frameworkElement != null)
            {
                if (frameworkElement.IsLoaded)
                {
                    frameworkElement.Unloaded += OnUnloaded;
                }
                else
                {
                    frameworkElement.Loaded += OnLoaded;
                }
            }

            var itemsControl = instance as ItemsControl;
            if (itemsControl != null)
            {
                itemsControl.ItemContainerGenerator.ItemsChanged += OnListChanged;
            }

            _children.CollectionChanged += OnChildenCountChanged;
        }
        protected override IList<Issue> AnalyzeInternal(TreeItem treeItem)
        {
            var issues = new List<Issue>();
            var dependencyObject = treeItem.Instance as DependencyObject;
            if (dependencyObject == null)
            {
                return issues;
            }

            foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(dependencyObject.GetType()))
            {
                var dpd = DependencyPropertyDescriptor.FromProperty(property);
                if (dpd != null && !dpd.IsReadOnly && dpd.PropertyType == typeof(Brush))
                {
                    var localValue = dependencyObject.ReadLocalValue(dpd.DependencyProperty);
                    var valueSource = DependencyPropertyHelper.GetValueSource(dependencyObject, dpd.DependencyProperty);
                    if (valueSource.BaseValueSource == BaseValueSource.Local && !valueSource.IsExpression)
                    {
                        if (localValue is Brush && localValue != Brushes.Transparent)
                        {
                            issues.Add(
                                new Issue( "LocalBrush",
                                    string.Format(
                                        "Property {0} contains the local brush {1}. Prevent local brushes to keep the design maintainable.",
                                        dpd.DisplayName, localValue), IssueSeverity.Message,
                                    IssueCategory.Maintainability, treeItem, dpd));
                        }
                    }
                }
            }

            return issues;
        }
示例#6
0
 /// <summary>
 /// Collapses the item.
 /// </summary>
 internal void CollapseItem(TreeItem item)
 {
     int removeIndex = _allItems.IndexOf(item) + 1;
     while ((removeIndex < _allItems.Count) && (_allItems[removeIndex].Level > item.Level))
     {
         _allItems.RemoveAt(removeIndex);
     }
 }
 private void AnalyzeResorucesRecursive(List<Issue> issues, ResourceDictionary dictionary, TreeItem treeItem)
 {
     foreach (var resourceDictionary in dictionary.MergedDictionaries)
     {
         AnalyzeResorucesRecursive(issues, resourceDictionary, treeItem);
     }
     CheckResources(issues,dictionary, treeItem);
 }
 protected override IList<Issue> AnalyzeInternal(TreeItem treeItem)
 {
     var issues = new List<Issue>();
     var fe = treeItem.Instance as FrameworkElement;
     if( fe != null)
     {
         AnalyzeResorucesRecursive(issues, fe.Resources, treeItem);
     }
     return issues;
 }
 protected override TreeItem CreateChild(object instance, TreeItem parent)
 {
     switch (_treeType)
     {
         case TreeType.LogicalTree:
             return new LogicalTreeItem(instance, parent, Model, 1);
         case TreeType.VisualTree:
             return new VisualTreeItem(instance, parent, Model, 1);
         default:
             throw new ArgumentException();
     }
 }
 protected override IList<Issue> AnalyzeInternal(TreeItem treeItem)
 {
     var issues = new List<Issue>();
     var markupObject = MarkupWriter.GetMarkupObjectFor(treeItem.Instance);
     if ( treeItem.Instance is Grid &&  treeItem.Children.Count <= 1 && markupObject.Properties.Count() == 0)
     {
         issues.Add(
             new Issue( "RedundantPanel","This panel seems to be redundant and can be removed. This reduces the tree dept and improves performance",
                 IssueSeverity.Warning, IssueCategory.Performance, treeItem));
     }
     return issues;
 }
 public void UpdateDataContext(TreeItem treeItem)
 {
     if (treeItem != null)
     {
         var fe = treeItem.Instance as FrameworkElement;
         if (fe != null && fe.DataContext != null)
         {
             _dataContextInfo.DataContext = fe.DataContext;
             return;
         }
     }
     _dataContextInfo.DataContext = null;
 }
示例#12
0
        public void UpdateTriggerList(TreeItem treeItem)
        {
            foreach (var triggerItem in _triggers)
            {
                triggerItem.Dispose();
            }

            _triggers.Clear();

            if (treeItem != null)
            {
                var fe = treeItem.Instance as FrameworkElement;
                if (fe != null)
                {
                    if (fe.Style != null)
                    {
                        AddTriggers(fe, fe.Style.Triggers, TriggerSource.Style);
                    }

                    AddTriggers(fe, fe.Triggers, TriggerSource.Element);
                }

                var control = treeItem.Instance as Control;
                if (control != null && control.Template != null)
                {
                    AddTriggers(control, control.Template.Triggers, TriggerSource.ControlTemplate);
                }

                var listBoxItem = treeItem.Instance as ListBoxItem;
                if (listBoxItem != null && listBoxItem.ContentTemplate != null)
                {
                    AddTriggers(listBoxItem, listBoxItem.ContentTemplate.Triggers, TriggerSource.DataTemplate);
                }

                var listViewItem = treeItem.Instance as ListViewItem;
                if (listViewItem != null && listViewItem.ContentTemplate != null)
                {
                    AddTriggers(listViewItem, listViewItem.ContentTemplate.Triggers, TriggerSource.DataTemplate);
                }

                var contentPresenter = treeItem.Instance as ContentPresenter;
                if (contentPresenter != null && contentPresenter.ContentTemplate != null)
                {
                    AddTriggers(contentPresenter, contentPresenter.ContentTemplate.Triggers, TriggerSource.DataTemplate);
                }
            }

            Triggers.Refresh();
        }
 private void CheckResources(List<Issue> issues, ResourceDictionary dictionary, TreeItem treeItem)
 {
     foreach (object resourceKey in dictionary.Keys)
     {
         var resource = dictionary[resourceKey];
         if (resource is Freezable && !((Freezable)resource).IsFrozen && !_reportedIssues.Contains(resourceKey))
         {
             _reportedIssues.Add(resourceKey);
             issues.Add(
                 new Issue( "Freeze Freezables",
                     string.Format("Freezing the resource {0} can save memory and increase performance.",
                                   resourceKey), IssueSeverity.Message, IssueCategory.Performance, treeItem));
         }
     }
 }
示例#14
0
        public void UpdateResourceList(TreeItem treeItem)
        {
            ResourceItems.Clear();

            if (treeItem != null)
            {
                var fe = treeItem.Instance as FrameworkElement;
                if (fe != null)
                {
                    ResourceItems.AddRange(ResourceItemFactory.GetResourcesForElement(fe));
                }
            }

            NotifyResourceListChanged();
        }
        protected override IList<Issue> AnalyzeInternal(TreeItem treeItem)
        {
            var issues = new List<Issue>();
            var frameworkElement = treeItem.Instance as FrameworkElement;
            if (frameworkElement == null)
            {
                return issues;
            }

            foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(frameworkElement.GetType()))
            {
                var dpd = DependencyPropertyDescriptor.FromProperty(property);
                if (dpd != null)
                {
                    var localValue = frameworkElement.ReadLocalValue(dpd.DependencyProperty);
                    if (localValue != null)
                    {
                        var localValueType = localValue.GetType();
                        if (localValueType.Name == "ResourceReferenceExpression")
                        {
                            var fieldInfo = localValueType.GetField("_resourceKey", BindingFlags.NonPublic | BindingFlags.Instance);
                            var resourceKey = fieldInfo.GetValue(localValue);

                            if (resourceKey != null)
                            {
                                var resource = frameworkElement.TryFindResource(resourceKey);
                                if( resource == null)
                                {
                                    issues.Add(
                                        new Issue("Resource not resolved",
                                            string.Format("The resource '{0}' on property '{1}' could not be resolved.",
                                                          resourceKey, dpd.DisplayName), IssueSeverity.Error,
                                            IssueCategory.Functionality, treeItem, dpd));
                                }
                            }
                        }
                    }

                }
            }

            return issues;
        }
示例#16
0
        /// <summary>
        /// Gets the xaml source for the specified tree item
        /// </summary>
        public string GetXamlSource(TreeItem treeItem)
        {
            while (!IsValidSource(treeItem) && treeItem != null)
            {
                treeItem = treeItem.Parent;
            }

            if (treeItem == null)
            {
                return string.Empty;
            }

            var name = treeItem.Instance.GetType().Name;

            foreach (var xamlSource in _xamlSources)
            {
                if (xamlSource.Key.Contains(name))
                {
                    return xamlSource.Value;
                }
            }
            return string.Empty;
        }
示例#17
0
        public LogicalTreeItem(object instance, TreeItem parent, TreeModel model, int level)
            : base(instance, parent, model, level)
        {
            var frameworkElement = instance as FrameworkElement;
            if (frameworkElement != null && !string.IsNullOrEmpty(frameworkElement.Name))
            {
                var name = frameworkElement.GetType().Name;
                Name = string.Format("{0} ({1})", name, frameworkElement.Name);
            }
            else
            {
                Name = instance.GetType().Name;
            }

            if (!LogicalTreeItemLookup.ContainsKey(instance))
            {
                LogicalTreeItemLookup.Add(instance, this);
            }
            else
            {
                LogicalTreeItemLookup[instance] = this;
            }
        }
        public void UpdateStyle(TreeItem treeItem)
        {
            ClearStyleItems();

            if (treeItem == null)
            {
                return;
            }

            var frameworkElement = treeItem.Instance as FrameworkElement;
            if (frameworkElement == null)
            {
                return;
            }

            // Resolve theme style
            var themeStyle = GetNamedThemeStyle(frameworkElement) ??
                             GetClassicThemeStyle(frameworkElement) ??
                             GetGenericThemeStyle(frameworkElement);
            if (themeStyle != null)
            {
                _styleItems.Add(themeStyle);
            }

            // Resolve default styles

            // Resolve local, inherited and app style
            var style = frameworkElement.GetValue(FrameworkElement.StyleProperty) as Style;
            if (style != null)
            {
                AddStyleRecursive(frameworkElement, style);
            }

            ApplyOverrides();

            OnStyleChanged();
        }
示例#19
0
        /// <summary>
        /// Expands the item.
        /// </summary>
        internal int ExpandItem(TreeItem item)
        {
            int childAdded = 0;
            int localAdded = 0;
            if (IsWholePathExpanded(item))
            {
                for (int i = 0; i < item.Children.Count; i++)
                {
                    int parentIndex = _allItems.IndexOf(item);
                    var child = item.Children[i];
                    if (!_allItems.Contains(child))
                    {
                        _allItems.Insert(parentIndex + childAdded + i + 1, child);
                        localAdded++;
                    }

                    if (child.IsExpanded)
                    {
                        childAdded += ExpandItem(child);
                    }
                }
            }
            return childAdded + localAdded;
        }
示例#20
0
 /// <summary>
 /// Removes the item.
 /// </summary>
 internal void RemoveItem(TreeItem item)
 {
     _allItems.Remove(item);
 }
示例#21
0
 protected abstract TreeItem CreateChild(object instance, TreeItem parent);
示例#22
0
 /// <summary>
 /// Updates the item.
 /// </summary>
 internal void UpdateItem(TreeItem item, IEnumerable<TreeItem> addedItems, IEnumerable<TreeItem> removedItems, int childenCountBefore)
 {
     if (IsWholePathExpanded(item))
     {
         int insertIndex = _allItems.IndexOf(item) + 1 + childenCountBefore;
         foreach (var removedItem in removedItems)
         {
             _allItems.Remove(removedItem);
         }
         foreach (var addedItem in addedItems)
         {
             _allItems.Insert(insertIndex++, addedItem);
         }
     }
 }
示例#23
0
 private static bool IsWholePathExpanded(TreeItem item)
 {
     while (item != null)
     {
         if (!item.IsExpanded)
         {
             return false;
         }
         item = item.Parent;
     }
     return true;
 }
示例#24
0
 protected override TreeItem CreateChild(object instance, TreeItem parent)
 {
     return new LogicalTreeItem(instance, parent, Model, Level+1);
 }
示例#25
0
 private void OnSelectedTreeItemChanged(object sender, EventArgs<TreeItem> e)
 {
     _selectedTreeItem = e.Data;
     _updateTrigger.IsUpdateRequired = true;
 }
示例#26
0
 protected virtual IList<Issue> AnalyzeInternal(TreeItem treeItem)
 {
     return new List<Issue>();
 }
示例#27
0
 /// <summary>
 /// Analyzes the specified element for issues.
 /// </summary>
 public virtual void Analyze(TreeItem treeItem, AnalyzerContext analyzerContext)
 {
     analyzerContext.UpdateIssues(this,treeItem, AnalyzeInternal(treeItem));
 }
        private void OnAdornerTimerTick(object sender, EventArgs e)
        {
            bool modifierPressed = Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl);

            // Start hovering
            if( modifierPressed && !_lastPressed)
            {
                _refreshTimer.Start();
            }

            // Stop hovering
            if (_lastPressed && !modifierPressed)
            {
                ApplySelectedTreeItem();
                _refreshTimer.Stop();
            }

            _lastPressed = modifierPressed;

            if (!modifierPressed)
                return;

            ActivateWindowAtMousePosition();

            var directlyOverElement = GetElementAtMousePos();
            if (DireclyOverElement != directlyOverElement)
            {
                FrameworkElement element = directlyOverElement;

                if (_selectedTreeItemService.SearchStrategy == SearchStrategy.LogicalTree)
                {
                    element = FindLogicalElement(element);
                }
                else
                {
                    // If SHIFT is pressed, automatically skip template parts and move up to the control itself
                    if (!Keyboard.IsKeyDown(Key.LeftShift) && !Keyboard.IsKeyDown(Key.RightShift))
                    {
                        while (element != null && element.TemplatedParent != null)
                        {
                            element = VisualTreeHelper.GetParent(element) as FrameworkElement;
                        }
                    }
                    _selectedTreeItem = VisualTreeItem.FindVisualTreeItem(element);
                }

                UpdateAdorner(element);
                DireclyOverElement = element;
                NotifyMouseElementChanged();
            }
        }
示例#29
0
 public AutomationItem(object item, TreeItem parent, TreeModel model, int level)
     : base(item, parent, model, level)
 {
     _element = (AutomationElement)item;
     Name     = _element.Current.ControlType.LocalizedControlType + " " + _element.Current.Name;
 }
        private FrameworkElement FindLogicalElement(FrameworkElement element)
        {
            _selectedTreeItem = LogicalTreeItem.FindLogicalTreeItem(element);

            while (_selectedTreeItem == null && element != null && element.TemplatedParent != null)
            {
                element = element.TemplatedParent as FrameworkElement;
                _selectedTreeItem = LogicalTreeItem.FindLogicalTreeItem(element);
            }

            while (_selectedTreeItem == null && element != null)
            {
                element = VisualTreeHelper.GetParent(element) as FrameworkElement;
                _selectedTreeItem = LogicalTreeItem.FindLogicalTreeItem(element);
            }
            return element;
        }
示例#31
0
 public AutomationItem(object item, TreeItem parent, TreeModel model, int level)
     : base(item, parent, model,level)
 {
     _element = (AutomationElement)item;
     Name = _element.Current.ControlType.LocalizedControlType + " " + _element.Current.Name;
 }
示例#32
0
 protected override TreeItem CreateChild(object instance, TreeItem parent)
 {
     return(new AutomationItem(instance, parent, Model, Level + 1));
 }