WPF: фон ComboBoxItem

У меня есть ComboBox на основе данных файла XML:

<Root>
<Node Background="Yellow" Foreground="Cyan" Image="1.ico" Property="aaaa" Value="28" />
<Node Background="SlateBlue" Foreground="Black" Image="2.ico" Property="bbbb" Value="2.5" />
<Node Background="Teal" Foreground="Green" Image="3.ico" Property="cccc" Value="4.0" />
<Node Background="Yellow" Foreground="Red" Image="4.ico" Property="dddd" Value="0" /></Root>

Итак, в этом случае мне нужно создать составной ComboBoxItem, когда каждый элемент имеет подходящий фон.

Я пробовал сделать что-то вроде этого:

    <UserControl.Resources>
    <DataTemplate DataType="Node">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" MinWidth="20"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="Auto" MinWidth="20"/>
            </Grid.ColumnDefinitions>
            <Border Background="{Binding XPath=@Background}" Grid.Column="0">
                <Image Source="{Binding XPath=@Image}" 
                       Width="16" 
                       Height="16" 
                       Margin="3" />
            </Border>
            <Border Background="{Binding XPath=@Background}" Grid.Column="1">
                <TextBlock Foreground="{Binding XPath=@Foreground}" 
                           Margin="3"
                           Text="{Binding XPath=@Property}" />
            </Border>
            <Border Background="{Binding XPath=@Background}" Grid.Column="2">
                <TextBlock Foreground="{Binding XPath=@Foreground}" 
                           Margin="3" 
                           FontWeight="Bold"
                           Text="{Binding XPath=@Value}" />
            </Border>
        </Grid>
    </DataTemplate>

    <XmlDataProvider x:Key="xmlNodeList" 
                     Source="/data/Combo.xml" 
                     XPath="/Root/Node"/>
</UserControl.Resources>

<ComboBox Name="myComboBox" 
          ItemsSource="{Binding Source={StaticResource xmlNodeList}}" 
          SelectedIndex="0" />

но это выглядит не очень хорошо :-(

Какое решение вы рекомендуете?

Заранее спасибо!


person user83493    schedule 03.05.2009    source источник


Ответы (1)


Во-первых, вы забыли указать, какой шаблон использовать:

<DataTemplate x:Key="Node">
      <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" MinWidth="20"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="Auto" MinWidth="20"/>
        </Grid.ColumnDefinitions>
        <Border Background="{Binding XPath=@Background}" Grid.Column="0">
            <Image Source="{Binding XPath=@Image}" 
                   Width="16" 
                   Height="16" 
                   Margin="3" />
        </Border>
        <Border Background="{Binding XPath=@Background}" Grid.Column="1">
            <TextBlock Foreground="{Binding XPath=@Foreground}" 
                       Margin="3"
                       Text="{Binding XPath=@Property}" />
        </Border>
        <Border Background="{Binding XPath=@Background}" Grid.Column="2">
            <TextBlock Foreground="{Binding XPath=@Foreground}" 
                       Margin="3" 
                       FontWeight="Bold"
                       Text="{Binding XPath=@Value}" />
        </Border>
    </Grid>
</DataTemplate>

А затем ваш ComboBox:

<ComboBox Name="myComboBox" 
          ItemsSource="{Binding Source={StaticResource xmlNodeList}}" 
          ItemTemplate="{StaticResource Node}"
          SelectedIndex="0" />

Система dataType работает с типизированными объектами, я не уверен, что вы сможете заставить ее работать с данными XML. Это сработает.

Обновление: прежде чем вы спросите, вы также должны определить стиль для элементов, чтобы они соответствовали ширине списка, иначе ваши столбцы будут неровными:

   <ComboBox Name="myComboBox"
                      ItemsSource="{Binding Source={StaticResource xmlNodeList}}"
                      ItemTemplate="{StaticResource Node}"
                      SelectedIndex="0">
                <ComboBox.ItemContainerStyle>
                    <Style TargetType="{x:Type ComboBoxItem}">
                        <Setter Property="HorizontalContentAlignment"
                                Value="Stretch" />
                    </Style>
                </ComboBox.ItemContainerStyle>
            </ComboBox>

Это растянет отдельные элементы, чтобы покрыть всю ширину списка.

person Denis Troller    schedule 04.05.2009
comment
Здравствуйте Денис, Спасибо за ответ! Я пробовал ваши предложения, но: 1. ItemTemplate = {StaticResource Node} генерирует ошибку времени выполнения: не удается найти ресурс с именем '{Node}' в методе InitializeComponent () 2. Добавлен стиль, ничего не изменилось 3. Одна из проблем, возникающая при наведении курсора мыши на ComboboxItems , выделение происходит под сеткой - person user83493; 04.05.2009
comment
обратите внимание на мое замечание, в котором говорится, что вам нужно указать атрибут x: Key = Node, а не DataType = Node для вашего DataTemplate. Это источник ошибки. - person Denis Troller; 04.05.2009
comment
Я обновил свой ответ, включив в него полный шаблон, так я понятнее. - person Denis Troller; 04.05.2009