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

时间:2015-08-25 12:54:42

标签: c# wpf visual-studio

我想要实现的目标:

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

  

public class 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";
}

这是XAML标记:

<UserControl ...
    xmlns:vsUiControls="clr-namespace:Microsoft.VisualStudio.Diagnostics.UI.Controls;assembly=Microsoft.VisualStudio.Diagnostics.Common"
    ...>
    <vsUiControls:MultiSelectComboBox x:Name="multiSelectComboBox"/>
</UserControl>

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

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

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

描述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>

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

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

1 个答案:

答案 0 :(得分: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>

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