6

我似乎无法为 ComboBoxItem 设置 ContentTemplate。我尝试这样做的原因是我想在组合框中为我的数据显示 2 次。当组合框打开(菜单关闭)时,我想要一个文本框(带有图像名称)和它下面的图像控件。当我选择项目时,我希望组合框只显示一个带有图像名称的文本框。

我想我可以通过修改 ComboBox 的 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 中的代码可能依赖于它的存在)。

任何有关显示具有不同下拉列表和选定模板的组合框的帮助将不胜感激!

4

3 回答 3

5

ComboBox.ItemTemplate 只是设置 ComboBoxItem.ContentTemplate 的一种便捷方式。因此,您上面的代码基本上尝试设置 ComboBoxItem.ContentTemplate 两次。

正如 Jobi 指出的那样,您可以尝试仅使用自定义样式。如果您始终知道 Content 的类型,则可以安全地排除 ContentPresenter。ContentPresenter 只允许您使用 DataTemplate 来显示一些随机数据。但是您可以将其替换为 TextBlock 和 Image。您只是失去了指定 DataTemplate 的能力。

Jobi 方法的问题在于,即使它在下拉列表中,选择项也不会显示它的图像。实际选中的项目显示在两个位置(下拉列表和 ComboBox 的主体)。在一个位置您需要一个 DataTemplate,而在另一个位置您需要一个不同的 DataTemplate。

最好的办法是重新设计 ComboBox。您可以从此处获取默认样式。有一个名为“ContentPresenter”的 ContentPresenter。您需要:

  1. 删除/更改 ContentPresenter 的名称,因此 ComboBox 不会自动设置 Content/ContentTemplate 属性
  2. 像这样绑定 ContentPresenter.Content 属性:“{TemplateBinding SelectedObject}”
  3. 将 ContentPresenter.ContentTemplate 属性设置为不带图像的 DataTemplate
  4. 使用 Image 和 TextBlock 将 ComboBox.ItemTemplate 属性设置为 DataTemplate
  5. 给 ComboBox Style 一个明确的键,例如 x:Key="MyComboBoxStyle"
  6. 使用 ComboBox 上的样式,例如 Style="{StaticResource MyComboBoxStyle}"

当在 ComboBox 的正文中显示所选项目时,这实际上会忽略 ComboBoxItem.ContentTemplate,但在下拉菜单中显示 ComboBoxItem 时会使用它。

于 2010-09-14T11:42:55.937 回答
0

您只需使用 ItemsContainerStyle 即可实现此目的。添加您的 TextBlock 和 Image 而不是 ContentPresenter。添加 VisualStateManager 并根据 VSM 的选定状态切换 Image 控件的可见性。

于 2008-11-07T10:26:14.717 回答
0

DataTemplate 主要是为了你的数据可视化,最好把所有 UI 相关的动态都放在 ControlTemplate(控制行为)里面。如果您没有 ContentPresenter,则没有潜在问题。唯一的问题是,如果您想从其他 ComboBox 重用此 ControlTemplate。然后你可以用 ContentPresenter 声明另一个干净的 Control 模板。

于 2008-11-20T21:59:09.220 回答