WPF - 根据项目模板更改组合框样式
Posted
技术标签:
【中文标题】WPF - 根据项目模板更改组合框样式【英文标题】:WPF - change combobox style depending on itemtemplate 【发布时间】:2019-03-07 02:36:18 【问题描述】:我需要创建一个组合,当它的下拉关闭时将显示一个简单的文本(枚举)值。但是当用户点击下拉菜单时,它应该在组合框项目中显示一个包含更多信息的复杂数据模板。
我创建了两个数据模板,用于在关闭或打开下拉菜单时显示不同的信息。
<DataTemplate x:Key="DropDownOpenedTemplate">
<ContentControl Content="Binding">
<ContentControl.Style>
<Style TargetType="x:Type ContentControl">
<!-- Complex template -->
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<DockPanel >
<Image Width="100" DockPanel.Dock="Left" Stretch="Uniform" Source="Binding ImageUri"
VerticalAlignment="Center" HorizontalAlignment="Center" Margin="0,0,15,0" />
<StackPanel DockPanel.Dock="Right" Orientation="Vertical">
<TextBlock Text="Binding Name" VerticalAlignment="Center" HorizontalAlignment="Left" FontStyle="Italic" FontWeight="Bold" Margin="10,0,0,5"/>
<TextBlock Text="Binding Description" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="25,0,0,0"/>
</StackPanel>
</DockPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</ContentControl.Style>
</ContentControl>
</DataTemplate>
<DataTemplate x:Key="DropDownClosedTemplate" >
<ContentControl Content="Binding">
<ContentControl.Style>
<Style TargetType="x:Type ContentControl">
<!-- default template -->
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="Binding Name" HorizontalAlignment="Stretch" />
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</ContentControl.Style>
</ContentControl>
</DataTemplate>
然后我创建了一个模板选择器,它将覆盖 SelectTemplate 方法
public override DataTemplate SelectTemplate(object item, DependencyObject container)
ContentPresenter presenter = (ContentPresenter)container;
FrameworkElement elemnt = container as FrameworkElement;
while (container != null)
container = VisualTreeHelper.GetParent(container);
if (container is ComboBoxItem)
return (DataTemplate)presenter.FindResource("DropDownOpenedTemplate"); ;
return (DataTemplate)presenter.FindResource("DropDownClosedTemplate");
此功能工作正常。但现在我需要根据使用的模板格式化样式。为简化起见,我需要在选择 dropdownclosetemplate 时组合框的背景颜色为蓝色,选择 dropdownopenedtemplate 时为黄色,并且所选项目的背景应为红色。
<ComboBox x:Name="spComboBox" Grid.Row="1"
Grid.Column="1"
Width="200"
Margin="30"
Background="Blue"
HorizontalAlignment="Center"
VerticalAlignment="Center"
ItemsSource="Binding ModeList"
SelectedValue="Binding SelectedMode, Mode=TwoWay"
ScrollViewer.CanContentScroll="False"
ItemTemplateSelector="StaticResource ComboBoxItemTemplateSelector">
<ComboBox.ItemContainerStyle>
<Style TargetType="ComboBoxItem">
<Setter Property="Background" Value="Yellow"/>
<Style.Triggers>
<DataTrigger Binding="Binding Path=IsDropDownOpen, RelativeSource=RelativeSource TemplatedParent" Value="False">
<Setter Property="Background" Value="Blue" />
</DataTrigger>
</Style.Triggers>
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>
我只能看到黄色,但不能在选择dropdownopededtemplate时更改DropdowncloseTemplate的样式,并选择DropdownopedTemplate时。
任何帮助将不胜感激。
【问题讨论】:
【参考方案1】:如果您不需要使用 relativesource= 而是使用 elementname=spComboBox,您可以轻松地进行绑定。但是,如果我正确理解了您的三个状态,我认为您根本不需要它(如果没有,请具体说明,也许带有显示所有状态的图像)。我添加了一个文本框来显示这种绑定。它也适用于数据触发器。但是我认为,如果您想对其进行测试,则应将其与 True 进行比较,而不是像您的示例中那样与 false 进行比较。
这是我的解决方案:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<StackPanel>
<ComboBox x:Name="spComboBox" Grid.Row="1"
Grid.Column="1"
Width="200"
Margin="30"
Background="Blue"
HorizontalAlignment="Center"
VerticalAlignment="Center"
ScrollViewer.CanContentScroll="False" >
<ComboBoxItem Name="cbi1">Item1</ComboBoxItem>
<ComboBoxItem Name="cbi2">Item2</ComboBoxItem>
<ComboBoxItem Name="cbi3">Item3</ComboBoxItem>
<ComboBox.ItemContainerStyle>
<Style TargetType="ComboBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBoxItem">
<Border x:Name="border" BorderThickness="1" Padding="3" Background="Yellow">
<ContentPresenter/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="border" Property="Background" Value="Red"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>
<TextBlock Text="Binding ElementName=spComboBox, Path=IsDropDownOpen"></TextBlock>
</StackPanel>
</Window>
当没有选择任何内容时,它显示蓝色。当你打开下拉菜单时,所有项目都是黄色的,如果你选择一个,背景=红色(虽然不容易立即看到,因为光标直接设置到它,隐藏颜色,但你会看到它是红色的,一旦你移动光标)
关闭状态下的背景色,this answer should help
【讨论】:
感谢简的回复。当存在模板选择器时,我无法通过仅更改背景属性将组合框的背景颜色更改为蓝色。使用 IsSelected 属性而不是 IsDropDownOpen 属性是正确的(我在代码中犯了一个错误),但即使将属性更改为 IsSelected,代码也不会更改所选组合框项的颜色。 @Dhan 你能检查一下 isselected 是否适用于我的代码位吗?来源:dotnetcurry.com/wpf/1211/wpf-items-control-advanced-topic @Dhan 我认为我答案中的最后一个链接应该可以解决最后一个问题,尽管它远非一个简单的解决方案以上是关于WPF - 根据项目模板更改组合框样式的主要内容,如果未能解决你的问题,请参考以下文章