2015-10-24 182 views
0

有沒有辦法遍歷所有的Visual Studio WPF元素?我試圖瞭解如何在Visual Studio擴展的上下文中添加額外的按鈕+上下文菜單條目。有沒有辦法遍歷visual studio shell?

是的,我知道Tab Studios的存在。如果這不起作用,我不妨試試,如果這符合我的需求。但在這一點上,我只是好奇如何做到這一點。

這裏是我迄今爲止嘗試:

enter image description here

internal class EditorMargin1 : StackPanel, IWpfTextViewMargin 
    { 
     /// <summary> 
     /// Margin name. 
     /// </summary> 
     public const string MarginName = "EditorMargin1"; 

     /// <summary> 
     /// A value indicating whether the object is disposed. 
     /// </summary> 
     private bool isDisposed; 

     /// <summary> 
     /// Initializes a new instance of the <see cref="EditorMargin1"/> class for a given <paramref name="textView"/>. 
     /// </summary> 
     /// <param name="textView">The <see cref="IWpfTextView"/> to attach the margin to.</param> 
     public EditorMargin1(IWpfTextView textView) 
     { 
      this.ClipToBounds = true; 

      var parents = GetParentsRecursive(textView); 

      var start = 60; 

      var white = new SolidColorBrush(Color.FromRgb((byte)255, (byte)255, (byte)255)); 
      white.Freeze(); 

      foreach (var parentElement in parents) 
      { 
       start += 20; 
       var background = new SolidColorBrush(Color.FromRgb((byte)start, (byte)0, (byte)start)); 

       var changedColor = false; 

       var colorableControl = parentElement as Control; 
       if (colorableControl != null) 
       { 
        colorableControl.Background = background; 
        changedColor = true; 
       } 

       this.Children.Add(new Label() 
       { 
        Foreground = white, 
        Background = background, 
        Content = "Hello EditorMargin1 " + parentElement.GetType().FullName + " has changed color " + changedColor, 
       }); 
      } 
     } 

     private IEnumerable<DependencyObject> GetParentsRecursive(IWpfTextView textView) 
     { 
      var control = textView as DependencyObject; 
      while (control != null) 
      { 
       yield return control; 
       control = LogicalTreeHelper.GetParent(control); 
      } 
     } 

     #region IWpfTextViewMargin 

     /// <summary> 
     /// Gets the <see FrameworkElementlement"/> that implements the visual representation of the margin. 
     /// </summary> 
     /// <exception cref="ObjectDisposedException">The margin is disposed.</exception> 
     public FrameworkElement VisualElement 
     { 
      // Since this margin implements Canvas, this is the object which renders 
      // the margin. 
      get 
      { 
       this.ThrowIfDisposed(); 
       return this; 
      } 
     } 

     #endregion 

     #region ITextViewMargin 

     /// <summary> 
     /// Gets the size of the margin. 
     /// </summary> 
     /// <remarks> 
     /// For a horizontal margin this is the height of the margin, 
     /// since the width will be determined by the <see cref="ITextView"/>. 
     /// For a vertical margin this is the width of the margin, 
     /// since the height will be determined by the <see cref="ITextView"/>. 
     /// </remarks> 
     /// <exception cref="ObjectDisposedException">The margin is disposed.</exception> 
     public double MarginSize 
     { 
      get 
      { 
       this.ThrowIfDisposed(); 

       // Since this is a horizontal margin, its width will be bound to the width of the text view. 
       // Therefore, its size is its height. 
       return this.ActualHeight; 
      } 
     } 

     /// <summary> 
     /// Gets a value indicating whether the margin is enabled. 
     /// </summary> 
     /// <exception cref="ObjectDisposedException">The margin is disposed.</exception> 
     public bool Enabled 
     { 
      get 
      { 
       this.ThrowIfDisposed(); 

       // The margin should always be enabled 
       return true; 
      } 
     } 

     /// <summary> 
     /// Gets the <see cref="ITextViewMargin"/> with the given <paramref name="marginName"/> or null if no match is found 
     /// </summary> 
     /// <param name="marginName">The name of the <see cref="ITextViewMargin"/></param> 
     /// <returns>The <see cref="ITextViewMargin"/> named <paramref name="marginName"/>, or null if no match is found.</returns> 
     /// <remarks> 
     /// A margin returns itself if it is passed its own name. If the name does not match and it is a container margin, it 
     /// forwards the call to its children. Margin name comparisons are case-insensitive. 
     /// </remarks> 
     /// <exception cref="ArgumentNullException"><paramref name="marginName"/> is null.</exception> 
     public ITextViewMargin GetTextViewMargin(string marginName) 
     { 
      return string.Equals(marginName, EditorMargin1.MarginName, StringComparison.OrdinalIgnoreCase) ? this : null; 
     } 

     /// <summary> 
     /// Disposes an instance of <see cref="EditorMargin1"/> class. 
     /// </summary> 
     public void Dispose() 
     { 
      if (!this.isDisposed) 
      { 
       GC.SuppressFinalize(this); 
       this.isDisposed = true; 
      } 
     } 

     #endregion 

     /// <summary> 
     /// Checks and throws <see cref="ObjectDisposedException"/> if the object is disposed. 
     /// </summary> 
     private void ThrowIfDisposed() 
     { 
      if (this.isDisposed) 
      { 
       throw new ObjectDisposedException(MarginName); 
      } 
     } 
    } 


    /// <summary> 
    /// Export a <see cref="IWpfTextViewMarginProvider"/>, which returns an instance of the margin for the editor to use. 
    /// </summary> 
    [Export(typeof(IWpfTextViewMarginProvider))] 
    [Name(EditorMargin1.MarginName)] 
// [Order(After = PredefinedMarginNames.HorizontalScrollBar)] // Ensure that the margin occurs below the horizontal scrollbar 
    [MarginContainer(PredefinedMarginNames.Top)]    // Set the container to the bottom of the editor window 
    [ContentType("text")]          // Show this margin for all text-based types 
    [TextViewRole(PredefinedTextViewRoles.Interactive)] 
    internal sealed class EditorMargin1Factory : IWpfTextViewMarginProvider 
    { 
     #region IWpfTextViewMarginProvider 

     /// <summary> 
     /// Creates an <see cref="IWpfTextViewMargin"/> for the given <see cref="IWpfTextViewHost"/>. 
     /// </summary> 
     /// <param name="wpfTextViewHost">The <see cref="IWpfTextViewHost"/> for which to create the <see cref="IWpfTextViewMargin"/>.</param> 
     /// <param name="marginContainer">The margin that will contain the newly-created margin.</param> 
     /// <returns>The <see cref="IWpfTextViewMargin"/>. 
     /// The value may be null if this <see cref="IWpfTextViewMarginProvider"/> does not participate for this context. 
     /// </returns> 
     public IWpfTextViewMargin CreateMargin(IWpfTextViewHost wpfTextViewHost, IWpfTextViewMargin marginContainer) 
     { 
      return new EditorMargin1(wpfTextViewHost.TextView); 
     } 

     #endregion 
    } 

我跑進去,從一個穿越點的問題,是我不能讓過去WpfTextViewHost。

有沒有人知道一種簡單的方法來遍歷窗口?

回答

1

遍歷所有的Visual Studio WPF元素,你可以從System.Windows.Application.Current.MainWindow啓動和使用System.Windows.Media.VisualTreeHelper.GetChild遞歸。請參閱以下示例代碼Hide title bar in Visual Studio 2013

+0

呃。我希望這不起作用。否則我會因爲沒有想到自己而感到有些慚愧。一旦我回家,我會看看它。提前致謝 – Dbl

相關問題