为什么当SelectedItem是ContentControl时,此ComboBox会忽略DataTemplate?

时间:2013-10-31 15:50:54

标签: c# wpf binding datatemplate

在我们的应用程序中,我们有一个屏幕设计功能,它由一个自定义的ScreenDesignPanel和一个Property Geite组成,顶部有一个ComboBox,指向ScreenDesignPanel上的选定项目。这允许用户通过ComboBox或通过鼠标选择UIElement来设置其属性。我们通过将ComboBox的ItemsSource绑定到ScreenDesignPanel的Children集合,然后将其SelectedItems绑定在一起来实现此目的。这很有效。

但是,无论出于何种原因,如果SelectedItemContentControl或子类如Button,则为ItemTemplate指定的ComboBox会被忽略“选定的项目区域”,但在下拉列表中显示项目时会应用它。如果SelectedItem不是ContentControl,则会在两种情况下使用模板。

这似乎也是ComboBox特有的。如果我们使用任何其他选择器控件:ListBoxListViewItemsControl ...甚至第三方ComboBox控制......他们全部按预期工作,正确应用DataTemplate。 ComboBox在内部做了一些其他控件没做的事情。

注意:下面是一个过于简化的示例,仅用于说明问题。这不是我们如上所述实际使用它的方式。

另外值得注意的是: 在ComboBox.ItemTemplate的DataTemplate中,我们只使用属性(例如示例中的Foreground),并且不显示DataContext(即实际的ContentControl)本身。 / em> 这很重要因为同样,ScreenDesignPanel上已经存在实际的控件,因此不能用于在ComboBox的ItemTemplate中显示,因为它有两个父母,它们不是允许。换句话说,它在这里纯粹用作数据。

最后一件事......我们的应用程序中有一个可行的解决方案,即在将Child绑定到ComboBox.ItemsSource之前将其包装起来。但是,我仍然很好奇为什么ComboBox的行为方式与 特定 的方式有关。 (换句话说,我不是在寻找这种设计的其他解决方案。我们已经有了一个有效的解决方案。我正在寻找ComboBox本身奇怪行为的清晰度。)

代码!

在下面的第一个示例中,请注意数据模板如何应用于下拉列表中的所有内容,但如果所选项目不是ContentControl,则所选项目区域仅使用模板。

<ComboBox>

    <ComboBox.ItemTemplate>

        <DataTemplate>
            <TextBlock Text="I am the template" Foreground="{Binding Foreground}" />
        </DataTemplate>

    </ComboBox.ItemTemplate>

            <!-- Four 'Data' items for example only -->
    <TextBlock Text="I am a Red TextBox" Foreground="Red"/>

    <ListBox Foreground="Purple">
        <ListBoxItem>I am a Purple ListBox</ListBoxItem>
    </ListBox>

    <ContentControl Content="I am a Blue ContentControl" Foreground="Blue" />

    <Button Content="I am a Button with Green text" Foreground="Green" />

</ComboBox>

第二个示例显示,使用UIElement作为ContentPresenter的内容并仍使用DataTemplate(通过ContentTemplate)完全可以接受并完全支持所以你可以在纯数据角色中使用它,允许模板本身定义视觉外观而不显示UIElement本身,这里纯粹用作数据。

<ContentPresenter>

    <ContentPresenter.ContentTemplate>

        <DataTemplate>
            <TextBlock Text="I am the ContentTemplate" Foreground="{Binding Foreground}" />
        </DataTemplate>

    </ContentPresenter.ContentTemplate>

    <ContentPresenter.Content>
        <Button Content="I am the button" Foreground="Green" />
    </ContentPresenter.Content>

</ContentPresenter>

同样,问题是具体ComboBox.我想找出为什么数据模板不适用于该单一案例,以及如何强制应用它,如果可能的话。

值得注意的是,ComboBox确实定义了SelectionBoxItemTemplate,它与常规的ItemTemplate是分开的,但是它是只读的,因此您无法设置它。我们真的不想重新模板ComboBox,因为这会弄乱正确的主题。

1 个答案:

答案 0 :(得分:0)

您是否尝试过将DataTemplate明确设置为ContentControl.ContentTemplate属性?:

<UserControl.Resources>
    <DataTemplate x:Key="DataTemplate">
        <TextBlock Text="{Binding Content, 
            StringFormat='Displayed via template: {0}'}" />
    </DataTemplate>
</UserControl.Resources>
...
<ContentControl Content="ContentControl" 
    ContentTemplate="{StaticResource DataTemplate}" />