如何使Microsoft.VisualStudio.Diagnostics.UI.Controls.MultiSelectComboBox工作

Sha*_*ron 10 c# wpf visual-studio

我想要实现的目标:

我正在开发一个Visual Studio插件,我需要一个MultiSelectComboBox.我想要适应VisualStudio的外观和感觉,所以使用自己的类似乎是个好主意:

公共类MultiSelectComboBox:UserControl,IComponentConnector,IStyleConnector
名称:Microsoft.VisualStudio.Diagnostics.UI.Controls.MultiSelectComboBox
程序集:Microsoft.VisualStudio.Diagnostics.Common,Version = 12.0.0.0

Microsoft在其"代码分析"页面中使用此类:查看/其他Windows /代码分析.

问题:

当然,当我想使用它时,它就无法正常工作.:)

这是我使用它的示例代码:

public TestClass()
{
    InitializeComponent();
    multiSelectComboBox.ItemsSource = new string[] { "Item 1", "Item 2", "Item 3" };
    multiSelectComboBox.AllItemsText = "All items";
}
Run Code Online (Sandbox Code Playgroud)

这是XAML标记:

<UserControl ...
    xmlns:vsUiControls="clr-namespace:Microsoft.VisualStudio.Diagnostics.UI.Controls;assembly=Microsoft.VisualStudio.Diagnostics.Common"
    ...>
    <vsUiControls:MultiSelectComboBox x:Name="multiSelectComboBox"/>
</UserControl>
Run Code Online (Sandbox Code Playgroud)

现在出现MultiSelectComboBox并且您可以与它进行交互,但是,当您选择一些项目时,但不是全部,项目应该显示如下:( Item 1; Item 3假设您选择了除项目2之外的所有项目).但是,显示的文本只是Item 1Item 3完全没有分隔符.

有趣的事情(我已经忽略了很长一段时间)是,如果你调试你的代码并要求multiSelectComboBox.SelectedItemsText它返回用分号分隔的正确值.

所以问题是,如果值存储正确,为什么在我的代码中使用它时它没有正确显示,但是当微软在代码分析页面上使用时呢?

描述MultiSelectComboBox样式的XAML标记只包含SelectedItemsText的一个实例,它是一个绑定.请看下面我从.Net Reflector获得的内容如下:

<local:MultiSelectComboBox
    p1:UserControl.Name="_this"
    p1:AutomationProperties.Name="{Binding RelativeSource={RelativeSource Self},Path=AllItemsText}"
    xmlns:p1="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:local="clr-namespace:Microsoft.VisualStudio.Diagnostics.UI.Controls;assembly=Microsoft.VisualStudio.Diagnostics.Common,Version=12.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a">
    ...
    <Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
        <local:CheckComboBox
            CheckComboBox.Name="_comboBox"
            p4:FrameworkElement.Style="{StaticResource ComboStyle}"
            p4:Control.HorizontalContentAlignment="Stretch"
            p4:KeyboardNavigation.DirectionalNavigation="Continue"
            p4:AutomationProperties.Name="{Binding ElementName=_this,Path=SelectedItemsText,Mode=OneWay}"
            xmlns:p4="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
            <ItemsControl.ItemTemplate>
                ...
            </ItemsControl.ItemTemplate>
        </local:CheckComboBox>
    </Grid>
</local:MultiSelectComboBox>
Run Code Online (Sandbox Code Playgroud)

我不确定为什么SelectedItemsText绑定AutomationProperties.Name(附加?)属性,但这就是.Net Reflector给了我的.如果我调试我的代码,我可以找到存储在控件Name属性中的分号分隔值.CheckedComboxBoxMultiSelectComboBox

值似乎存储正确,绑定似乎工作,但显示到UI的文本不包含分隔符.我只是感到困惑......

Nik*_*lay 2

我查看了反编译的源代码,似乎属性 SelectedItemsText 仅用于 UI 自动化(附加属性 AutomationProperties.Name)。真实的显示文本使用以下 XAML 显示:

<TextBlock Name="PART_SummaryPartialSelection" Grid.Row="0" Style="{StaticResource DropDownTextBlockStyle}" Visibility="{Binding Path=AllItemsSelected, ElementName=_this, Converter={StaticResource booleanToVisibilityConverterNegative}}">
  <ItemsControl Name="PART_Items" Focusable="False" Background="#00FFFFFF" IsHitTestVisible="False" x:Uid="M113" ItemsSource="{Binding SelectedItems, ElementName=_this}" ItemTemplate="{Binding DisplayAreaTemplate, ElementName=_this}">
    <ItemsControl.ItemsPanel>
      <ItemsPanelTemplate x:Uid="M115">
        <StackPanel IsItemsHost="True" Orientation="Horizontal" x:Uid="M116" />
    </ItemsPanelTemplate>
  </ItemsControl.ItemsPanel>
  </ItemsControl>
</TextBlock>
Run Code Online (Sandbox Code Playgroud)

所以它只是水平的 StackPanel,其中的项目一一对应,没有任何分隔符。因此,您需要修改此模板或仅在项目中添加分号(看起来 Visual Studio 是这样做的,因为它在最后一项之后显示分号事件 - item1; item2;)