Что я пытаюсь достичь:
Я разрабатываю плагин 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";
}
И здесь разметка 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 на странице анализа кода?
Разметка XAML, описывающая стиль MultiSelectComboBox, содержит только один экземпляр 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
(прикрепленный?), но это то, что дал мне Reflector.Net. Если я отлаживаю свой код, я могу найти значения, разделенные точкой с запятой, хранящиеся в свойстве Name
элемента управления CheckedComboxBox
в MultiSelectComboBox
.
Значения, похоже, сохранены правильно, привязка, похоже, работает, но текст, отображаемый в пользовательском интерфейсе, не содержит разделителя. Я просто озадачен...