【问题标题】:ComboBox Style problems with DisplayMemberPathDisplayMemberPath 的组合框样式问题
【发布时间】:2009-04-24 10:43:10
【问题描述】:

我有一个 ComboBox 并且我已将 combo.ItemsSource 属性设置为一个 List 对象。 Book 类包含两个属性:“Abbreviation”“Name”。

我已将 ComboBox 的 DisplayMemberPath 设置为“Abbreviation”,但在 ComboBox 上设置的以下样式不显示 Abbreviation 属性,而是显示“Words.Book”,这是类的名称。 ComboBox 下拉列表正确显示列表(使用指定的 Abbreviation 属性)。问题出在选择的 ComboBox 项中,当 ComboBox 的下拉菜单关闭时显示。

我猜问题出在 DataTemplate 的 ContentPresenter 中,但我找不到成功的解决方案。目前 ContentPresenter 的 Content 属性设置为 Content="{TemplateBinding Content} 但我不知道是否应该这样。

任何想法如何在所选项目上显示 DisplayMemberPath 中指定的属性?

谢谢

代码:

<ControlTemplate x:Key="ComboBoxToggleButton" TargetType="ToggleButton">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition Width="20" />
        </Grid.ColumnDefinitions>
        <Border x:Name="Border" Grid.ColumnSpan="2" CornerRadius="2" BorderThickness="1" Background="{DynamicResource ribbonTitleFade}" />
        <Border Grid.Column="0" CornerRadius="2,0,0,2" Margin="1,6,1,6" BorderBrush="{DynamicResource boSecE}" BorderThickness="0,0,1,0" />
        <Path x:Name="Arrow" Grid.Column="1" Fill="White" 
              HorizontalAlignment="Center" VerticalAlignment="Center" Data="M 0 0 L 4 4 L 8 0 Z"
              />
    </Grid>
    <ControlTemplate.Triggers>
        <Trigger Property="ToggleButton.IsMouseOver" Value="true">
            <Setter TargetName="Border" Property="Background" Value="{DynamicResource ribbonTitleFade}" />
        </Trigger>
        <Trigger Property="ToggleButton.IsChecked" Value="true">
            <Setter TargetName="Border" Property="Background" Value="{DynamicResource ribbonTitleFade}" />
        </Trigger>
        <Trigger Property="IsEnabled" Value="False">
            <Setter TargetName="Border" Property="Background" Value="Black" />
            <Setter TargetName="Border" Property="BorderBrush" Value="Black" />
            <Setter Property="Foreground" Value="Gray"/>
            <Setter TargetName="Arrow" Property="Fill" Value="Gray" />
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

<Style x:Key="comboBoxBorderTransparent" TargetType="Control">
    <Setter Property="BorderBrush" Value="{DynamicResource boPrimC}" />
</Style>


<Style x:Key="comboItemStyle" TargetType="ComboBoxItem">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ComboBoxItem}">
                <Border x:Name="backBorder" >
                    <StackPanel Orientation="Horizontal">
                        <Rectangle x:Name="rectA" Stroke="White" Width="4" Height="4" Fill="#80FFFFFF" Margin="5,0,0,0" HorizontalAlignment="Left" />
                        <TextBlock x:Name="text" Foreground="White" FontSize="10px">
                            <ContentPresenter Margin="8,1,0,1"
                                              SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" 
                                              HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                                              VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                              />
                        </TextBlock>
                    </StackPanel>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="ComboBoxItem.IsMouseOver" Value="true">
                        <Setter TargetName="rectA" Property="Stroke" Value="Black" />
                        <Setter TargetName="rectA" Property="Fill" Value="#80000000" />
                        <Setter TargetName="backBorder" Property="Background" Value="White"/>
                        <Setter TargetName="text" Property="Foreground" Value="{DynamicResource boPrimC}"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<DataTemplate x:Key="comboSelectedItemTemplate">
    <TextBlock Foreground="White" FontSize="10px">
        <ContentPresenter Content="{TemplateBinding Content}" />
    </TextBlock>
</DataTemplate>

<Style TargetType="ComboBox">
    <Setter Property="SnapsToDevicePixels" Value="true"/>
    <Setter Property="OverridesDefaultStyle" Value="true"/>
    <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
    <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
    <Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
    <Setter Property="MinWidth" Value="60"/>
    <Setter Property="MinHeight" Value="20"/>
    <Setter Property="ItemContainerStyle" Value="{DynamicResource comboItemStyle}"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ComboBox">
                <Grid>
                    <ToggleButton 
                        Name="ToggleButton" Grid.Column="2" 
                        Template="{StaticResource ComboBoxToggleButton}" 
                        Focusable="false"
                        IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
                        ClickMode="Press">
                    </ToggleButton>

                    <ContentPresenter HorizontalAlignment="Center"
                                      VerticalAlignment="Center"
                                      Name="ContentSite"
                                      IsHitTestVisible="False" 
                                      Content="{TemplateBinding SelectionBoxItem}"
                                      ContentTemplate="{DynamicResource comboSelectedItemTemplate}"
                                      ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
                                      Margin="3,3,23,3"
                                      />

                    <Popup Name="Popup" Placement="Bottom" IsOpen="{TemplateBinding IsDropDownOpen}"
                           AllowsTransparency="False" Focusable="False" PopupAnimation="Slide">
                        <Grid Name="DropDown" SnapsToDevicePixels="True" 
                              MinWidth="{TemplateBinding ActualWidth}" MaxHeight="{TemplateBinding MaxDropDownHeight}">
                            <Border x:Name="DropDownBorder" Background="{DynamicResource ribbonTitleFade}"
                                    BorderThickness="1" BorderBrush="{DynamicResource boPrimC}" />
                            <ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True">
                                <StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
                            </ScrollViewer>
                        </Grid>
                    </Popup>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="HasItems" Value="false">
                        <Setter TargetName="DropDownBorder" Property="MinHeight" Value="95"/>
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Foreground" Value="Black"/>
                    </Trigger>
                    <Trigger Property="IsGrouping" Value="true">
                        <Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
                    </Trigger>
                    <Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="true">
                        <Setter TargetName="DropDownBorder" Property="CornerRadius" Value="2"/>
                        <Setter TargetName="DropDownBorder" Property="Margin" Value="0"/>
                    </Trigger>
                    <Trigger Property="IsEditable" Value="true">
                        <Setter Property="IsTabStop" Value="false"/>
                        <!--<Setter TargetName="ContentSite" Property="Visibility" Value="Hidden"/>-->
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
    </Style.Triggers>
</Style>

【问题讨论】:

    标签: wpf templates combobox styles selecteditem


    【解决方案1】:

    我认为您希望在您的 ComboBox 模板中添加类似的内容:

    <ContentPresenter Content="{TemplateBinding ComboBox.SelectionBoxItem}"
     ContentTemplate="{TemplateBinding ComboBox.SelectionBoxItemTemplate}"
     ContentStringFormat="{TemplateBinding ComboBox.SelectionBoxItemStringFormat}"
     Margin="{TemplateBinding Control.Padding}"
     HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
     VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}"
     SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
    

    【讨论】:

    • 我已按照您的建议更改了 Content、ContentTemplate 和 ContentStringFormat,并开始按应有的方式显示。现在,唯一的问题是我不知道在哪里设置文本的前景画笔应该是白色的。我以前在 DataTemplate 中这样做过,但是由于不再使用此 DataTemplate,所以放置 Foreground="White" 的正确位置在哪里?谢谢
    • 我认为您可以在 ComboBoxItem.ItemContainerStyle 上放置一个触发器,当 IsSelected = true 时将前景更改为白色。
    • ComboBoxItem.ItemContainerStyle 反映下拉列表中的项目。我需要的是选定项目的前景(关闭下拉菜单时)。目前,这是设置: ContentTemplate="{TemplateBinding ComboBox.SelectionBoxItemTemplate}" 但我不知道如何更改 ComboBox.SelectionBoxItemTemplate。
    • 尝试:ContentTemplateSelector={TemplateBinding ItemTemplateSelector} 如果您使用与弹出窗口相同的 Controltemplate
    【解决方案2】:

    如果您的模板没有明确处理DisplayMemberPath 的值,则模板不会使用它来更改ComboBoxItem。您必须直接在ControlTemplate 中绑定到该成员,或使用单独的DataTemplate

    【讨论】:

      【解决方案3】:

      我发现 BureauBlack 主题 存在问题,它不会应用 DisplayMemberPath,只是显示对象名称。我有一个包含许多 (15+) ComboBoxes 的窗口,除了 2 个以外的所有 ComboBoxes 都使用 DisplayMemberPath 正常工作。

      我从 ContentPresenters 和 GridViewRowPresenters 中删除了以下内容:

      Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"
      

      ListBoxItem、ComboBoxItem、ListViewItem 中。可能还有更多需要修复的地方,但这就是我们发现我们正在使用的全部内容。

      使用 Microsoft.Net 4.0 框架。我没有尝试 4.5 或 3.5。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-12
        • 1970-01-01
        • 1970-01-01
        • 2021-02-04
        • 2019-04-30
        • 1970-01-01
        相关资源
        最近更新 更多