这是我的组合框。
<ComboBox Height="45" HorizontalAlignment="Left" Margin="184,66,0,0" Name="ComboBox1" VerticalAlignment="Top" Width="216">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Label Content="{Binding FullName}" Width="150" />
<Label Content="{Binding Title}" Width="100"/>
<Label Content="{Binding BranchName}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
如何更改它以便只有FullName出现在组合框的文本框部分中,而所有三列仍然出现在下拉部分中?
答案 0 :(得分:30)
不幸的是,SelectionBoxItemTemplate
是一个只读属性,因此我们需要做更多的工作。通过ItemTemplate
选择项目的显示方式,您可以修改ItemContainerStyle
以提供包含您要显示的其他字段的ControlTemplate
。
<ComboBox Height="45" HorizontalAlignment="Left" Margin="184,66,0,0" Name="ComboBox1" VerticalAlignment="Top" Width="216">
<ComboBox.ItemTemplate>
<DataTemplate>
<Label Content="{Binding FullName}" Width="150" />
</DataTemplate>
</ComboBox.ItemTemplate>
<ComboBox.ItemContainerStyle>
<Style TargetType="{x:Type ComboBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBoxItem}">
<Border x:Name="Bd"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}">
<StackPanel Orientation="Horizontal">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
<Label Content="{Binding Title}" Width="100"/>
<Label Content="{Binding BranchName}" />
</StackPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsHighlighted" Value="True">
<Setter TargetName="Bd" Property="Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>
对于ComboBoxItem
模板,我只修改了默认模板,因此它应该完全正常运行。
答案 1 :(得分:7)
如果ComboBox的IsEditable属性设置为True,则可以将ComboBox的“TextSearch.TextPath”属性设置为要显示的属性名称。所以在你的情况下:
<ComboBox IsEditable="True" TextSearch.TextPath="FullName" .../>
答案 2 :(得分:2)
我没有使用只读的SelectionBoxItemTemplate属性,而是创建了一个新的(附加的,可写的)属性,并在我的样式中使用了该属性。我还为我的风格添加了一个触发器,以便不破坏所有未使用我新附加属性的组合框...
像这样使用:
<ComboBox ItemsSource="{Binding ...}" SelectedItem="{Binding ..., Mode=TwoWay}">
<controls:ComboBoxSelectionBoxAltTemplateBehaviour.SelectionBoxAltTemplate>
<DataTemplate DataType="{x:Type ...}">
... Template for the selection box ...
</DataTemplate>
</controls:ComboBoxSelectionBoxAltTemplateBehaviour.SelectionBoxAltTemplate>
<ComboBox.ItemTemplate>
<DataTemplate DataType="{x:Type ...}">
... Template for the popup ...
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
您只需将此类添加到项目中:
public class ComboBoxSelectionBoxAltTemplateBehaviour
{
public static readonly DependencyProperty SelectionBoxAltTemplateProperty = DependencyProperty.RegisterAttached(
"SelectionBoxAltTemplate", typeof (DataTemplate), typeof (ComboBoxSelectionBoxAltTemplateBehaviour), new PropertyMetadata(default(DataTemplate)));
public static void SetSelectionBoxAltTemplate(DependencyObject element, DataTemplate value)
{
element.SetValue(SelectionBoxAltTemplateProperty, value);
}
public static DataTemplate GetSelectionBoxAltTemplate(DependencyObject element)
{
return (DataTemplate) element.GetValue(SelectionBoxAltTemplateProperty);
}
}
并更改您的ComboBox样式以使用SelectionBoxAltTemplate附加属性(如果设置)(或者因为我无法将触发器设置为“not null”),如果附加的值为null,则将其设置回默认的SelectionBoxItemTemplate:
ComboBox样式的ControlTemplate中的ContentPresenter:
<ContentPresenter Content="{TemplateBinding SelectionBoxItem}" ContentTemplate="{TemplateBinding controls:ComboBoxSelectionBoxAltTemplateBehaviour.SelectionBoxAltTemplate}" />
触发器向ComboBoxed提供向后兼容性而没有附加属性:
<ControlTemplate.Triggers>
<Trigger Property="controls:ComboBoxSelectionBoxAltTemplateBehaviour.SelectionBoxAltTemplate" Value="{x:Null}">
<Setter Property="ContentTemplate" Value="{Binding SelectionBoxItemTemplate, RelativeSource={RelativeSource TemplatedParent}}" TargetName="ContentSite" />
</Trigger>
...
</ControlTemplate.Triggers>
完整风格:
<Style x:Key="{x:Type ComboBox}" TargetType="{x:Type ComboBox}">
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="FontSize" Value="12" />
<Setter Property="Background" Value="{StaticResource ComboBoxBackground}"/>
<Setter Property="BorderBrush" Value="{StaticResource ComboBoxBorder}"/>
<Setter Property="Margin" Value="6"/>
<Setter Property="Padding" Value="3,3,5,3"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBox}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Border Name="Border" Grid.ColumnSpan="2" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"/>
<ToggleButton Name="ToggleButton2" Focusable="False" IsChecked="{Binding Path=IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" ClickMode="Press" Grid.ColumnSpan="2" Background="Transparent"/>
<!-- Allows clicking anywhere on the combobox, not only the visible button on the right -->
<ToggleButton Focusable="false" Grid.Column="1" x:Name="ToggleButton" IsChecked="{Binding Path=IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" ClickMode="Press" Style="{StaticResource ComboBoxToggleButton}"/>
<ContentPresenter HorizontalAlignment="Left" Margin="{TemplateBinding Control.Padding}" x:Name="ContentSite" VerticalAlignment="Center" Content="{TemplateBinding SelectionBoxItem}" ContentTemplate="{TemplateBinding controls:ComboBoxSelectionBoxAltTemplateBehaviour.SelectionBoxAltTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" IsHitTestVisible="False" />
<TextBox Visibility="Hidden" HorizontalAlignment="Left" Margin="{TemplateBinding Control.Padding}" x:Name="PART_EditableTextBox" Style="{x:Null}" VerticalAlignment="Center" Focusable="True" Background="Transparent" />
<Popup IsOpen="{TemplateBinding IsDropDownOpen}" Placement="Bottom" x:Name="Popup" Focusable="False" AllowsTransparency="True" PopupAnimation="Slide">
<Grid MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{TemplateBinding ActualWidth}" x:Name="DropDown" SnapsToDevicePixels="True">
<Border x:Name="DropDownBorder" Background="{StaticResource ComboBoxBackground}" BorderBrush="{StaticResource ComboBoxBorder}" BorderThickness="1" Padding="0,4">
<ScrollViewer SnapsToDevicePixels="True" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" CanContentScroll="True" Style="{x:Null}" >
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained"/>
</ScrollViewer>
</Border>
</Grid>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="controls:ComboBoxSelectionBoxAltTemplateBehaviour.SelectionBoxAltTemplate" Value="{x:Null}">
<Setter Property="ContentTemplate" Value="{Binding SelectionBoxItemTemplate, RelativeSource={RelativeSource TemplatedParent}}" TargetName="ContentSite" />
</Trigger>
<Trigger Property="HasItems" Value="false">
<Setter Property="MinHeight" Value="95" TargetName="DropDownBorder" />
</Trigger>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false" />
</Trigger>
<Trigger Property="IsEditable" Value="true">
<Setter Property="IsTabStop" Value="false" />
<Setter Property="Visibility" Value="Visible" TargetName="PART_EditableTextBox" />
<Setter Property="Visibility" Value="Hidden" TargetName="ContentSite" />
</Trigger>
<Trigger Property="IsMouseOver" Value="true" SourceName="ToggleButton2">
<Setter Property="Background" Value="{StaticResource ComboBoxMouseOver}" />
</Trigger>
<Trigger Property="HasItems" Value="False">
<Setter Property="IsEnabled" Value="False"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
然而,这可能不适用于ItemTemplateSelctors,只能使用一个模板 - 但您可以轻松添加附加属性“SelectionBoxAltTemplateSelector”,它提供选择器并将其传递给样式。
答案 3 :(得分:1)
如果您不想更改ComboBox样式,那么您的问题可以得到很好的答案:https://stackoverflow.com/a/2277488/1070906
它在DataTemplate中使用一个Trigger,它在可视化树中查看上面某处是否存在ComboBoxItem,而在选择框中则不是这样。
答案 4 :(得分:0)
您可以覆盖ComboBox并直接更改SelectionBoxItemTemplate。
public class SelectionComboBox : ComboBox
{
#region Properties
#region Dependency Properties
public DataTemplate AltSelectionBoxItemTemplate
{
get { return (DataTemplate)GetValue(AltSelectionBoxItemTemplateProperty); }
set { SetValue(AltSelectionBoxItemTemplateProperty, value); }
}
public static readonly DependencyProperty AltSelectionBoxItemTemplateProperty =
DependencyProperty.Register("AltSelectionBoxItemTemplate", typeof(DataTemplate), typeof(SelectionComboBox), new UIPropertyMetadata(null, (s, e) =>
{
// For new changes...
if ((s is SelectionComboBox) && ((SelectionComboBox)s).Presenter != null && (e.NewValue is DataTemplate))
((SelectionComboBox)s).Presenter.ContentTemplate = (DataTemplate)e.NewValue;
// Set the new value
((SelectionComboBox)s).AltSelectionBoxItemTemplate = (DataTemplate)e.NewValue;
}));
#endregion
#region Internals
#region Elements
ContentPresenter Presenter { get; set; }
#endregion
#endregion
#endregion
#region Constructors
#endregion
#region Methods
#region Overrides
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
Presenter = this.GetTemplateChild("contentPresenter") as ContentPresenter;
// Directly Set the selected item template
if (AltSelectionBoxItemTemplate != null) Presenter.ContentTemplate = AltSelectionBoxItemTemplate;
}
#endregion
#endregion
}
一旦定义了控件,就可以对其进行样式设置。
<controls:SelectionComboBox ItemsSource="{Binding ...}" SelectedItem="{Binding ..., Mode=TwoWay}">
<controls:SelectionComboBox.AltSelectionBoxItemTemplate>
<DataTemplate>
<!-- My Template Goes Here... -->
</DataTemplate>
</controls:SelectionComboBox.AltSelectionBoxItemTemplate>
</controls:SelectionComboBox>