VSIX扩展自定义窗口显示类名而非内容问题求助
VSIX扩展自定义提示窗口XAML未加载问题解决
问题描述
在Visual Studio 2019的VSIX/C#扩展中,尝试实现带关闭按钮的自定义提示窗口,从主AsyncPackage的InitializeAsync方法调用ShowHintWindow启动窗口,但VSIX启动后窗口仅显示hintWindow类名,对应的XAML内容未加载。相关代码如下:
初始化代码
protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress) { ... ShowHintWindow(); } private void ShowHintWindow() { var hintWindow = new MyNameSpace.hintWindow.hintWindow(); var window = new System.Windows.Window { Content = hintWindow, Title = "Hint", SizeToContent = System.Windows.SizeToContent.WidthAndHeight }; window.Owner = System.Windows.Application.Current.MainWindow; window.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen; window.Show(); }
hintWindowControl XAML代码
<UserControl x:Class="MyNameSpace.hintWindow.hintWindowControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:vsshell="clr-namespace:Microsoft.VisualStudio.Shell;assembly=Microsoft.VisualStudio.Shell.15.0" Background="{DynamicResource {x:Static vsshell:VsBrushes.WindowKey}}" Foreground="{DynamicResource {x:Static vsshell:VsBrushes.WindowTextKey}}" mc:Ignorable="d" IsVisibleChanged="MyToolWindow_IsVisibleChanged" Name="MyToolWindow" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"> <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Keyboard.KeyDown="Grid_KeyDown"> <StackPanel Margin="10"> <TextBlock Text="Notification" FontSize="16" FontWeight="Bold" Margin="0,0,0,10"/> <TextBlock Text="{Binding MainText}" TextWrapping="Wrap" Margin="0,0,0,10"/> <StackPanel Orientation="Horizontal"> <Button Content="Ok" Width="100" Height="30" Margin="0,0,10,0" /> <Button Content="Don't show again" Width="150" Height="30" /> </StackPanel> </StackPanel> </Grid> </UserControl>
hintWindow类代码
public class hintWindow : ToolWindowPane { public hintWindow() : base(null) { this.Caption = "HintWindow Search"; this.Content = new hintWindowControl(this); } }
问题原因
ToolWindowPane是Visual Studio扩展中用于创建工具窗口的专用容器类,它本身并非WPF控件。直接将ToolWindowPane实例赋值给WPFWindow的Content属性时,WPF无法识别其内部的hintWindowControl,只会默认显示类的字符串表示(即类名)。
解决方法
方法1:直接使用UserControl作为窗口内容
跳过ToolWindowPane,直接将hintWindowControl作为WPF窗口的内容:
private void ShowHintWindow() { var hintControl = new MyNameSpace.hintWindow.hintWindowControl(); var window = new System.Windows.Window { Content = hintControl, Title = "Hint", SizeToContent = System.Windows.SizeToContent.WidthAndHeight }; window.Owner = System.Windows.Application.Current.MainWindow; window.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen; window.Show(); }
方法2:保留ToolWindowPane,使用其内部Content
如果需要保留hintWindow类的逻辑,可提取ToolWindowPane已初始化的Content作为窗口内容:
private void ShowHintWindow() { var hintWindow = new MyNameSpace.hintWindow.hintWindow(); var window = new System.Windows.Window { Content = hintWindow.Content, Title = "Hint", SizeToContent = System.Windows.SizeToContent.WidthAndHeight }; window.Owner = System.Windows.Application.Current.MainWindow; window.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen; window.Show(); }
额外优化:确保在UI线程操作
VS扩展中所有UI操作必须在主UI线程执行,建议在InitializeAsync中切换线程后再调用窗口显示:
protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress) { ... // 切换到主UI线程 await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); ShowHintWindow(); }
内容的提问来源于stack exchange,提问作者pf12345678910
相关产品推荐
相关产品推荐

