2008-11-07 21 views
6

我似乎无法为ComboBoxItem设置ContentTemplate。我试图做到这一点的原因是我想为组合框中的数据出现两次。当组合框打开(菜单向下)时,我需要一个文本框(带有图像的名称)和一个位于其下方的图像控件。当我选择该项目时,我希望组合框只显示一个带有图像名称的文本框。如何在Silverlight组合框中为选定和下拉状态使用不同的模板?

我想我可以通过修改组合框的ItemTemplate和ItemContainerStyle来实现这一点。该ItemContainerStyle包含以下ContentPresenter:

<ContentPresenter HorizontalAlignment="Left" Margin="{TemplateBinding Padding}" x:Name="contentPresenter" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/> 

所以,我认为我可以只设置的ContentTemplate在这里,它会工作。但我似乎无法得到它的工作:

<DataTemplate x:Key="ComboBoxDataTemplate"> 
      <Grid> 
       <TextBlock Text="{Binding Path='Name'}"/> 
      </Grid> 
     </DataTemplate> 

<DataTemplate x:Key="ComboBoxItemTemplate"> 
      <StackPanel> 
       <TextBlock Text="{Binding Path='Name'}"/> 
       <Image Source="{Binding Path='Source'}" Width="64" Height="64"/> 
      </StackPanel> 
     </DataTemplate> 

     <Style x:Key="ComboBoxItemStyle1" TargetType="ComboBoxItem"> 
... 
      <Setter Property="ContentTemplate" Value="{StaticResource ComboBoxItemTemplate}"/> 

... 

这里是我的组合框:

<ComboBox Width="70" Margin="3,0,0,0" 
         ItemsSource="{StaticResource Source}" 
         ItemTemplate="{StaticResource ComboBoxDataTemplate}" 
         ItemContainerStyle="{StaticResource ComboBoxItemStyle1}" 
         /> 

我能得到这个工作的唯一方法是从ItemContainerStyle删除ContentPresenter,并将其替换为我的自定义模板(ComboBoxItemTemplate)的内容。但我认为我不应该使用这种方法,因为这意味着ContentPresenter不再存在(并且ComboBox中的代码可能依赖于它)。

任何帮助显示组合框与不同的下拉菜单和选定的模板将不胜感激!

回答

5

ComboBox.ItemTemplate是设置ComboBoxItem.ContentTemplate的简便方法。所以你上面的代码基本上试图设置ComboBoxItem.ContentTemplate两次。如Jobii指出的那样,您可以尝试使用一种自定义样式。如果您始终知道内容的类型,则可以安全地排除ContentPresenter。 ContentPresenter只允许您使用DataTemplate显示一些随机数据。但你可以用TextBlock和Image来代替它。你只是失去了指定DataTemplate的能力。

Jobi的方法存在的问题是,选择的项目不会显示它的图像,即使它在下拉菜单中。真的,所选项目显示在两个位置(ComboBox的下拉菜单和主体)中。在一个位置需要一个DataTemplate,并且在另一个位置需要另一个DataTemplate。

最好的办法是重新组合框。你可以从here得到默认的风格。有一个名为“ContentPresenter”的ContentPresenter。你将需要:

  1. 删除/修改ContentPresenter的名字,所以组合框不会自动设置Content /的ContentTemplate属性
  2. 绑定ContentPresenter。内容属性,如下:“{TemplateBinding SelectedObject}”
  3. 将ContentPresenter.ContentTemplate属性为您的DataTemplate没有图像
  4. 的ComboBox.ItemTemplate属性设置为DataTemplate中具有图像和TextBlock的你就像是
  5. 给组合框风格明确的重点,如x:键=“MyComboBoxStyle”
  6. 使用您的组合框风格,像风格=“{StaticResource的MyComboBoxStyle}”

显示时,这有效地忽略了ComboBoxItem.ContentTemplate选定的迭代m在ComboBox的主体中,但在下拉列表中显示ComboBoxItem时使用它。

+0

真的很有帮助。谢谢。只是为了澄清,我正在努力取代'SelectedObject',尽管现在看起来很明显。我对ContentPresenter的代码片段看起来是这样的: 2011-10-17 16:10:14

0

你可以用ItemsContainerStyle来实现。添加您的TextBlock和图像,而不是ContentPresenter。添加VisualStateManager并根据VSM的Selected状态切换Image控件的可见性。

+0

那么ItemTemplate的要点是什么,并且不会有ContentPresenter导致潜在的问题? – 2008-11-07 14:31:50

0

DataTemplate主要用于您的数据可视化,最好在ControlTemplate(控件行为)中给出与UI相关的所有动态。如果您没有ContentPresenter,则不存在潜在问题。唯一的问题是,如果你想从其他ComboBox中重用这个ControlTemplate。然后,您可以在那里声明另一个带有ContentPresenter的干净控制模板。

相关问题