wpf 使用了 template 了的 combobox 中,displaymemberpath 有 bug,仅在 popup 中生效
需求是:仅想改变combobox的默认样式,所以 template 是直接在属性窗口点击转化为本地值的。
using System.Collections.Generic; using System.Windows; namespace WpfApp2 { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); var list = new List<MyClass> { new MyClass { Name = "lwieru" } }; a.ItemsSource = aa.ItemsSource = list; a.SelectedItem = aa.SelectedItem = list[0]; } class MyClass { public string Name { get; set; } } } }
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero2" x:Class="WpfApp2.MainWindow"> <StackPanel> <ComboBox x:Name="a" DisplayMemberPath="Name"/> <ComboBox x:Name="aa" DisplayMemberPath="Name"> <ComboBox.Template> <ControlTemplate TargetType="{x:Type ComboBox}"> <Grid x:Name="templateRoot" SnapsToDevicePixels="True"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition MinWidth="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" Width="0"/> </Grid.ColumnDefinitions> <Popup x:Name="PART_Popup" AllowsTransparency="True" Grid.ColumnSpan="2" IsOpen="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Margin="1" PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom"> <Themes:SystemDropShadowChrome x:Name="shadow" Color="Transparent" MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{Binding ActualWidth, ElementName=templateRoot}"> <Border x:Name="DropDownBorder" BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}" BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"> <ScrollViewer x:Name="DropDownScrollViewer"> <Grid x:Name="grid" RenderOptions.ClearTypeHint="Enabled"> <Canvas x:Name="canvas" HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0"> <Rectangle x:Name="OpaqueRect" Fill="{Binding Background, ElementName=DropDownBorder}" Height="{Binding ActualHeight, ElementName=DropDownBorder}" Width="{Binding ActualWidth, ElementName=DropDownBorder}"/> </Canvas> <ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Contained" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> </Grid> </ScrollViewer> </Border> </Themes:SystemDropShadowChrome> </Popup> <ToggleButton x:Name="toggleButton" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.ColumnSpan="2" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"> <ToggleButton.Style> <Style TargetType="{x:Type ToggleButton}"> <Setter Property="OverridesDefaultStyle" Value="True"/> <Setter Property="IsTabStop" Value="False"/> <Setter Property="Focusable" Value="False"/> <Setter Property="ClickMode" Value="Press"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ToggleButton}"> <Border x:Name="templateRoot" BorderBrush="#FFACACAC" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="True"> <Border.Background> <LinearGradientBrush EndPoint="0,1" StartPoint="0,0"> <GradientStop Color="#FFF0F0F0" Offset="0"/> <GradientStop Color="#FFE5E5E5" Offset="1"/> </LinearGradientBrush> </Border.Background> <Border x:Name="splitBorder" BorderBrush="Transparent" BorderThickness="1" HorizontalAlignment="Right" Margin="0" SnapsToDevicePixels="True" Width="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}"> <Path x:Name="Arrow" Data="F1M0,0L2.667,2.66665 5.3334,0 5.3334,-1.78168 2.6667,0.88501 0,-1.78168 0,0z" Fill="#FF606060" HorizontalAlignment="Center" Margin="0" VerticalAlignment="Center"/> </Border> </Border> <ControlTemplate.Triggers> <MultiDataTrigger> <MultiDataTrigger.Conditions> <Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type ComboBox}}}" Value="true"/> <Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Self}}" Value="false"/> <Condition Binding="{Binding IsPressed, RelativeSource={RelativeSource Self}}" Value="false"/> <Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Self}}" Value="true"/> </MultiDataTrigger.Conditions> <Setter Property="Background" TargetName="templateRoot" Value="White"/> <Setter Property="BorderBrush" TargetName="templateRoot" Value="#FFABADB3"/> <Setter Property="Background" TargetName="splitBorder" Value="Transparent"/> <Setter Property="BorderBrush" TargetName="splitBorder" Value="Transparent"/> </MultiDataTrigger> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Fill" TargetName="Arrow" Value="Black"/> </Trigger> <MultiDataTrigger> <MultiDataTrigger.Conditions> <Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Self}}" Value="true"/> <Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type ComboBox}}}" Value="false"/> </MultiDataTrigger.Conditions> <Setter Property="Background" TargetName="templateRoot"> <Setter.Value> <LinearGradientBrush EndPoint="0,1" StartPoint="0,0"> <GradientStop Color="#FFECF4FC" Offset="0"/> <GradientStop Color="#FFDCECFC" Offset="1"/> </LinearGradientBrush> </Setter.Value> </Setter> <Setter Property="BorderBrush" TargetName="templateRoot" Value="#FF7EB4EA"/> </MultiDataTrigger> <MultiDataTrigger> <MultiDataTrigger.Conditions> <Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Self}}" Value="true"/> <Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type ComboBox}}}" Value="true"/> </MultiDataTrigger.Conditions> <Setter Property="Background" TargetName="templateRoot" Value="White"/> <Setter Property="BorderBrush" TargetName="templateRoot" Value="#FF7EB4EA"/> <Setter Property="Background" TargetName="splitBorder"> <Setter.Value> <LinearGradientBrush EndPoint="0,1" StartPoint="0,0"> <GradientStop Color="#FFEBF4FC" Offset="0"/> <GradientStop Color="#FFDCECFC" Offset="1"/> </LinearGradientBrush> </Setter.Value> </Setter> <Setter Property="BorderBrush" TargetName="splitBorder" Value="#FF7EB4EA"/> </MultiDataTrigger> <Trigger Property="IsPressed" Value="True"> <Setter Property="Fill" TargetName="Arrow" Value="Black"/> </Trigger> <MultiDataTrigger> <MultiDataTrigger.Conditions> <Condition Binding="{Binding IsPressed, RelativeSource={RelativeSource Self}}" Value="true"/> <Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type ComboBox}}}" Value="false"/> </MultiDataTrigger.Conditions> <Setter Property="Background" TargetName="templateRoot"> <Setter.Value> <LinearGradientBrush EndPoint="0,1" StartPoint="0,0"> <GradientStop Color="#FFDAECFC" Offset="0"/> <GradientStop Color="#FFC4E0FC" Offset="1"/> </LinearGradientBrush> </Setter.Value> </Setter> <Setter Property="BorderBrush" TargetName="templateRoot" Value="#FF569DE5"/> </MultiDataTrigger> <MultiDataTrigger> <MultiDataTrigger.Conditions> <Condition Binding="{Binding IsPressed, RelativeSource={RelativeSource Self}}" Value="true"/> <Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type ComboBox}}}" Value="true"/> </MultiDataTrigger.Conditions> <Setter Property="Background" TargetName="templateRoot" Value="White"/> <Setter Property="BorderBrush" TargetName="templateRoot" Value="#FF569DE5"/> <Setter Property="Background" TargetName="splitBorder"> <Setter.Value> <LinearGradientBrush EndPoint="0,1" StartPoint="0,0"> <GradientStop Color="#FFDAEBFC" Offset="0"/> <GradientStop Color="#FFC4E0FC" Offset="1"/> </LinearGradientBrush> </Setter.Value> </Setter> <Setter Property="BorderBrush" TargetName="splitBorder" Value="#FF569DE5"/> </MultiDataTrigger> <Trigger Property="IsEnabled" Value="False"> <Setter Property="Fill" TargetName="Arrow" Value="#FFBFBFBF"/> </Trigger> <MultiDataTrigger> <MultiDataTrigger.Conditions> <Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Self}}" Value="false"/> <Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type ComboBox}}}" Value="false"/> </MultiDataTrigger.Conditions> <Setter Property="Background" TargetName="templateRoot" Value="#FFF0F0F0"/> <Setter Property="BorderBrush" TargetName="templateRoot" Value="#FFD9D9D9"/> </MultiDataTrigger> <MultiDataTrigger> <MultiDataTrigger.Conditions> <Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Self}}" Value="false"/> <Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type ComboBox}}}" Value="true"/> </MultiDataTrigger.Conditions> <Setter Property="Background" TargetName="templateRoot" Value="White"/> <Setter Property="BorderBrush" TargetName="templateRoot" Value="#FFBFBFBF"/> <Setter Property="Background" TargetName="splitBorder" Value="Transparent"/> <Setter Property="BorderBrush" TargetName="splitBorder" Value="Transparent"/> </MultiDataTrigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> </ToggleButton.Style> </ToggleButton> <ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" Content="{TemplateBinding SelectionBoxItem}" ContentStringFormat="{TemplateBinding SelectionBoxItemStringFormat}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" IsHitTestVisible="False" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> </Grid> <ControlTemplate.Triggers> <Trigger Property="HasDropShadow" SourceName="PART_Popup" Value="True"> <Setter Property="Margin" TargetName="shadow" Value="0,0,5,5"/> <Setter Property="Color" TargetName="shadow" Value="#71000000"/> </Trigger> <Trigger Property="HasItems" Value="False"> <Setter Property="Height" TargetName="DropDownBorder" Value="95"/> </Trigger> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="IsGrouping" Value="True"/> <Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="False"/> </MultiTrigger.Conditions> <Setter Property="ScrollViewer.CanContentScroll" Value="False"/> </MultiTrigger> <Trigger Property="CanContentScroll" SourceName="DropDownScrollViewer" Value="False"> <Setter Property="Canvas.Top" TargetName="OpaqueRect" Value="{Binding VerticalOffset, ElementName=DropDownScrollViewer}"/> <Setter Property="Canvas.Left" TargetName="OpaqueRect" Value="{Binding HorizontalOffset, ElementName=DropDownScrollViewer}"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </ComboBox.Template> </ComboBox> </StackPanel> </Window>