其他远程 UI 概念

本文扩展了入门的 远程 UI 教程中涵盖的基础概念,并探讨以下附加主题:

上下文菜单

可以通过分配 FrameworkElementContextMenu ”属性,将上下文菜单从 XAML(可扩展应用程序标记语言)添加到远程 UI 控件。 此过程反映了在标准 WPF(Windows Presentation Foundation)中添加上下文菜单的方式。

<TextBox Text="Some text">
    <TextBox.ContextMenu>
      <ContextMenu Style="{DynamicResource {x:Static styles:VsResourceKeys.ContextMenuStyleKey}}">
        <MenuItem Header="Do something" Command="{Binding FirstCommand}" />
        <MenuItem Header="Do something else" Command="{Binding SecondCommand}">
          <MenuItem.Icon>
            <vs:Image Source="KnownMonikers.ClearWindowContent" />
          </MenuItem.Icon>
        </MenuItem>
      </ContextMenu>
    </TextBox.ContextMenu>
</TextBox>

在前面的示例中,该 vs:Image 控件用于将图像添加到上下文菜单项的标头( 后续图像部分中的更多详细信息)。 确保在 XAML 文件中引用 vsstyles 命名空间。

<DataTemplate xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              xmlns:vs="http://schemas.microsoft.com/visualstudio/extensibility/2022/xaml"
              xmlns:styles="clr-namespace:Microsoft.VisualStudio.Shell;assembly=Microsoft.VisualStudio.Shell.15.0"
              xmlns:colors="clr-namespace:Microsoft.VisualStudio.PlatformUI;assembly=Microsoft.VisualStudio.Shell.15.0">

每个菜单项的命令绑定到一个 AsyncCommand (有关详细信息,请参阅 远程 UI 教程):

[DataContract]
internal class MyToolWindowData : NotifyPropertyChangedObject
{
    public MyToolWindowData()
    {
        FirstCommand = new(async (commandParameter, cancellationToken) => ...);
        SecondCommand = new(async (commandParameter, cancellationToken) => ...);
    }

    [DataMember]
    public IAsyncCommand FirstCommand { get; }

    [DataMember]
    public IAsyncCommand SecondCommand { get; }
}

映像

可以使用远程用户界面 XAML 显示自定义图像或 Visual Studio 图像目录中的图像。

以下示例演示如何显示由 Visual Studio 映像目录提供的图像 ClearWindowContent。 它还详细介绍了向扩展项目添加自定义映像(名为 Images\MyCustomImage.16.16.png的文件)。 有关将图像添加到扩展的详细信息,请参阅 命令文章

<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
    <Border>
        <vs:Image Source="KnownMonikers.ClearWindowContent" />
    </Border>
    <Border>
        <vs:Image Source="MyCustomImage" />
    </Border>
</StackPanel>

与往常一样,请务必在XAML文件中引用vsstyles命名空间。

<DataTemplate xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              xmlns:vs="http://schemas.microsoft.com/visualstudio/extensibility/2022/xaml"
              xmlns:styles="clr-namespace:Microsoft.VisualStudio.Shell;assembly=Microsoft.VisualStudio.Shell.15.0"
              xmlns:colors="clr-namespace:Microsoft.VisualStudio.PlatformUI;assembly=Microsoft.VisualStudio.Shell.15.0">

还可以将 Source 属性的数据绑定到字符串或 ImageMoniker

<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
    <Border BorderThickness="2" BorderBrush="Red" Margin="2">
        <vs:Image Source="{Binding StringImage}" />
    </Border>
    <Border BorderThickness="2" BorderBrush="Red" Margin="2">
        <vs:Image Source="{Binding StringImageFromCatalog}" />
    </Border>
    <Border BorderThickness="2" BorderBrush="Red" Margin="2">
        <vs:Image Source="{Binding MonikerImage}" />
    </Border>
    <Border BorderThickness="2" BorderBrush="Red" Margin="2">
        <vs:Image Source="{Binding MonikerImageFromCatalog}" />
    </Border>
</StackPanel>

相应的数据上下文为:

[DataContract]
internal class MyToolWindowData
{
    [DataMember]
    public string StringImage { get; } = "MyCustomImage";

    [DataMember]
    public string StringImageFromCatalog { get; } = "KnownMonikers.ClearWindowContent";

    [DataMember]
    public ImageMoniker MonikerImage { get; } = ImageMoniker.Custom("MyCustomImage");

    [DataMember]
    public ImageMoniker MonikerImageFromCatalog { get; } = ImageMoniker.KnownValues.ClearWindowContent;
}

有关远程 UI 基础知识,请参阅 远程 UI 教程。 有关更高级的方案,请参阅 高级远程 UI 概念