0
有沒有辦法遍歷所有的Visual Studio WPF元素?我試圖瞭解如何在Visual Studio擴展的上下文中添加額外的按鈕+上下文菜單條目。有沒有辦法遍歷visual studio shell?
是的,我知道Tab Studios的存在。如果這不起作用,我不妨試試,如果這符合我的需求。但在這一點上,我只是好奇如何做到這一點。
這裏是我迄今爲止嘗試:
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。
有沒有人知道一種簡單的方法來遍歷窗口?
呃。我希望這不起作用。否則我會因爲沒有想到自己而感到有些慚愧。一旦我回家,我會看看它。提前致謝 – Dbl