WPF ComboBox

来源:互联网 发布:j2ee与java的区别 编辑:程序博客网 时间:2024/05/16 07:08

ScrollViewer样式参考http://blog.csdn.net/oneonce/article/details/77160487


效果


Sytle

<ResourceDictionary    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    xmlns:ctrls="clr-namespace:ImageButtonTest01.Control"    xmlns:converter="clr-namespace:ImageButtonTest01.Control.Converter">    <converter:BoolToVisibility x:Key="BTV"/>    <converter:PlaceholderFontSizeConverter x:Key="PHFSC"/>    <converter:ImageTextBoxMarginLeftConverter x:Key="ITBMLC"/>    <converter:BoolOppositeConverter x:Key="BOC"/>    <SolidColorBrush x:Key="ComboToggleButton.MouseMove.Foreground" Color="#FF7AC0EE"/>    <SolidColorBrush x:Key="ComboToggleButton.Checked.Foreground" Color="#801AC0EE"/>        <Style x:Key="ComboToggleButtonStyle" TargetType="{x:Type ToggleButton}">        <Setter Property="Background" Value="Transparent"/>        <Setter Property="BorderThickness" Value="0"/>        <Setter Property="BorderBrush" Value="Transparent"/>        <Setter Property="Template">            <Setter.Value>                <ControlTemplate TargetType="{x:Type ToggleButton}">                    <Border Background="Transparent">                        <Grid>                            <Grid.ColumnDefinitions>                                <ColumnDefinition Width="*"/>                                <ColumnDefinition Width="Auto"/>                            </Grid.ColumnDefinitions>                            <TextBlock x:Name="txt" Grid.Column="1" RenderTransformOrigin="0.5,0.5"                                       HorizontalAlignment="Center" VerticalAlignment="Center"                                       FontFamily="/ImageButtonTest01;component/Resources/#iconfont"                                       Text=""                                       Foreground="{Binding Foreground, RelativeSource={RelativeSource TemplatedParent}}">                                <TextBlock.RenderTransform>                                    <RotateTransform x:Name="transIcon" Angle="0"/>                                </TextBlock.RenderTransform>                            </TextBlock>                        </Grid>                    </Border>                    <ControlTemplate.Triggers>                        <MultiTrigger>                            <MultiTrigger.Conditions>                                <Condition Property="IsChecked" Value="true"></Condition>                            </MultiTrigger.Conditions>                            <Setter TargetName="txt" Property="Foreground" Value="{StaticResource ComboToggleButton.Checked.Foreground}"/>                            <MultiTrigger.EnterActions>                                <BeginStoryboard>                                    <Storyboard>                                        <DoubleAnimation Storyboard.TargetName="transIcon" Storyboard.TargetProperty="Angle" To="180" Duration="0:0:0.2" />                                    </Storyboard>                                </BeginStoryboard>                            </MultiTrigger.EnterActions>                            <MultiTrigger.ExitActions>                                <BeginStoryboard>                                    <Storyboard>                                        <DoubleAnimation Storyboard.TargetName="transIcon" Storyboard.TargetProperty="Angle" To="0" Duration="0:0:0.2" />                                    </Storyboard>                                </BeginStoryboard>                            </MultiTrigger.ExitActions>                        </MultiTrigger>                                                <Trigger Property="IsMouseOver" Value="True">                            <Setter TargetName="txt" Property="Foreground" Value="{StaticResource ComboToggleButton.MouseMove.Foreground}"/>                        </Trigger>                    </ControlTemplate.Triggers>                </ControlTemplate>            </Setter.Value>        </Setter>    </Style>    <Style x:Key="EditableTextBoxStyle" TargetType="{x:Type TextBox}">        <Setter Property="Margin" Value="1"/>        <Setter Property="Padding" Value="0"/>        <Setter Property="BorderThickness" Value="0"/>        <Setter Property="Background" Value="{x:Null}"/>        <Setter Property="MaxLength" Value="2048"/>        <Setter Property="Foreground" Value="Black"/>        <Setter Property="ContextMenu" Value="{DynamicResource TextBoxContextMenu}"/>        <Setter Property="SelectionBrush" Value="Bisque"/>        <Setter Property="FontSize" Value="16"/>        <Setter Property="Focusable" Value="True"/>        <Setter Property="CaretBrush" Value="Black"/>        <Setter Property="VerticalAlignment" Value="Center"/>        <Setter Property="SnapsToDevicePixels" Value="True"/>        <Style.Triggers>            <Trigger Property="IsReadOnly" Value="True">                <Setter Property="Opacity" Value="0.8"/>            </Trigger>            <Trigger Property="IsEnabled" Value="False">                <Setter Property="Opacity" Value="0.4"/>            </Trigger>        </Style.Triggers>    </Style>    <SolidColorBrush x:Key="PlaceholderComboBox.Static.BorderBrush" Color="#FF909090"/>    <SolidColorBrush x:Key="PlaceholderComboBox.Static.Foreground" Color="#FFAAAAAA"/>    <SolidColorBrush x:Key="PlaceholderComboBox.Focused.BorderBrush" Color="#FF007ACC"/>    <SolidColorBrush x:Key="PlaceholderComboBox.MouseOver.BorderBrush" Color="#FF1E1E1E"/>    <ControlTemplate x:Key="placeholderComboBoxTemplate" TargetType="{x:Type ctrls:PlaceholderComboBox}">        <Border x:Name="border"                Background="{TemplateBinding Background}"                BorderBrush="{StaticResource PlaceholderComboBox.Static.BorderBrush}"                BorderThickness="{TemplateBinding BorderThickness}"                HorizontalAlignment="Stretch" VerticalAlignment="Stretch"                CornerRadius="{Binding CornerRadius, RelativeSource={RelativeSource TemplatedParent}}">            <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">                <Grid.ColumnDefinitions>                    <!--左圆角-->                    <ColumnDefinition Width="{Binding CornerRadius.TopLeft, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource ITBMLC}, ConverterParameter=0.4}"/>                    <!--内容显示-->                    <ColumnDefinition Width="*"/>                    <!--清除按钮-->                    <ColumnDefinition Width="Auto"/>                    <!--下拉按钮-->                    <ColumnDefinition Width="Auto"/>                    <!--右圆角-->                    <ColumnDefinition Width="Auto"/>                </Grid.ColumnDefinitions>                <TextBlock x:Name="PART_Placeholder" Grid.Column="1" Margin="3,0,0,0"                           IsHitTestVisible="False"                           HorizontalAlignment="Left" VerticalAlignment="Center"                           SnapsToDevicePixels="True"                           Visibility="Collapsed" Opacity="0.6"                           TextAlignment="Left"                           Text="{Binding Path=PlaceHolder, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"                           FontSize="{Binding FontSize, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource PHFSC}}"/>                <ctrls:ImageButton x:Name="PART_ClearButton" Grid.Column="2"                                   Margin="2" IsTabStop="False" IsEnabled="True"                                   FontFamily="/ImageButtonTest01;component/Resources/#iconfont" FontSize="20"                                   Content=""                                   HorizontalAlignment="Right"                                   VerticalAlignment="Center"                                   Style="{StaticResource ImageButtonTransparent}"                                   Visibility="{Binding ShowClearButton,RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource BTV}}"/>                <Grid Grid.Column="1" x:Name="ContentSite">                    <ContentPresenter x:Name="PART_SelectedItem" ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"                                      ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"                                      Content="{TemplateBinding SelectionBoxItem}"                                      ContentStringFormat="{TemplateBinding SelectionBoxItemStringFormat}"                                      HorizontalAlignment="Stretch" Margin="2,0,2,0"                                      IsHitTestVisible="False" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"                                      VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>                                        <TextBox  x:Name="PART_EditableTextBox" Style="{StaticResource EditableTextBoxStyle}"                              Visibility="Collapsed" IsHitTestVisible="True"                              SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"                              HorizontalAlignment="Stretch" VerticalAlignment="Center"                              HorizontalContentAlignment="Left" TextAlignment="Left"                              IsReadOnly="{TemplateBinding IsReadOnly}"                              FontFamily="{TemplateBinding FontFamily}"                              Foreground="{TemplateBinding Foreground}"                              Text="{TemplateBinding Text}"                              FontSize="{TemplateBinding FontSize}"/>                </Grid>                <ToggleButton x:Name="PART_DropDownToggle" Grid.Column="1" Grid.ColumnSpan="3"                              BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"                              Background="{Binding Background,RelativeSource={RelativeSource TemplatedParent}}"                              Foreground="Black" FontWeight="Medium"                              IsEnabled="{Binding Path=IsReadOnly,RelativeSource={RelativeSource TemplatedParent},Mode=OneWay, Converter={StaticResource BOC}}"                              IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"                              Style="{StaticResource ComboToggleButtonStyle}">                    <ToggleButton.RenderTransform>                        <RotateTransform x:Name="transIcon" Angle="0"/>                    </ToggleButton.RenderTransform>                </ToggleButton>                <!--弹出下拉控件-->                <Popup x:Name="PART_Popup" AllowsTransparency="True" Focusable="False"                       IsOpen="{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}"                       PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}"                       Placement="Bottom">                    <Grid Background="#FFFFFFFF"                          Width="{Binding ActualWidth, RelativeSource={RelativeSource TemplatedParent}}"                          MaxHeight="{Binding MaxDropDownHeight, RelativeSource={RelativeSource TemplatedParent}}">                        <Border x:Name="PopupBorder" BorderThickness="{TemplateBinding BorderThickness}" HorizontalAlignment="Stretch"                                Height="Auto" BorderBrush="{TemplateBinding BorderBrush}"                                Background="Transparent">                        </Border>                        <ScrollViewer x:Name="DropDownScrollViewer"                                      HorizontalAlignment="Stretch" VerticalAlignment="Stretch"                                      VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto"                                      Style="{StaticResource scrollviewerDefaultStyle}">                            <ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Contained" />                        </ScrollViewer>                    </Grid>                </Popup>            </Grid>        </Border>        <ControlTemplate.Triggers>            <DataTrigger Binding="{Binding Text, RelativeSource={RelativeSource Self}}" Value="">                <Setter TargetName="PART_Placeholder" Property="Visibility" Value="Visible" />                <Setter TargetName="PART_ClearButton" Property="IsEnabled" Value="False" />            </DataTrigger>            <Trigger Property="IsEditable" Value="True">                <Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible"/>                <Setter TargetName="PART_SelectedItem" Property="Visibility" Value="Collapsed"/>                <Setter TargetName="PART_DropDownToggle" Property="Background" Value="Transparent"/>                <Setter TargetName="PART_DropDownToggle" Property="Grid.Column" Value="3"/>                <Setter TargetName="PART_DropDownToggle" Property="Grid.ColumnSpan" Value="1"/>                <Setter Property="IsTabStop" Value="false"/>                <Setter TargetName="PART_DropDownToggle" Property="Focusable" Value="False"/>            </Trigger>            <Trigger Property="IsMouseOver" Value="True">                <Setter TargetName="border" Property="BorderBrush" Value="{StaticResource PlaceholderComboBox.MouseOver.BorderBrush}"/>                <Setter TargetName="PART_DropDownToggle" Property="Foreground" Value="{StaticResource PlaceholderComboBox.MouseOver.BorderBrush}"/>            </Trigger>                        <Trigger Property="IsFocused" Value="True">                <Setter TargetName="border" Property="BorderBrush" Value="red"/>            </Trigger>                        <Trigger Property="IsKeyboardFocusWithin" Value="True">                <Setter TargetName="border" Property="BorderBrush" Value="{StaticResource PlaceholderComboBox.Focused.BorderBrush}"/>            </Trigger>            <Trigger Property="IsEnabled" Value="False">                <Setter TargetName="border" Property="Opacity" Value="0.4"/>            </Trigger>            <Trigger Property="IsStylusCaptured" Value="True">            </Trigger>        </ControlTemplate.Triggers>    </ControlTemplate>    <Style TargetType="{x:Type ctrls:PlaceholderComboBox}">        <Setter Property="AllowDrop" Value="true"/>        <Setter Property="Background" Value="WhiteSmoke"/>        <Setter Property="BorderThickness" Value="2"/>        <Setter Property="ScrollViewer.CanContentScroll" Value="true"/>        <Setter Property="BorderBrush" Value="{StaticResource ImageTextBox.Static.BorderBrush}"/>        <Setter Property="Template" Value="{StaticResource placeholderComboBoxTemplate}"/>    </Style></ResourceDictionary>



CS:

public class PlaceholderComboBox : ComboBox{    private ImageButton mClearTextButton;    static PlaceholderComboBox()    {        DefaultStyleKeyProperty.OverrideMetadata(typeof(PlaceholderComboBox), new FrameworkPropertyMetadata(typeof(PlaceholderComboBox)));    }    public PlaceholderComboBox()    {    }    public override void OnApplyTemplate()    {        mClearTextButton = GetTemplateChild("PART_ClearButton") as ImageButton;        if (null != mClearTextButton)        {            mClearTextButton.Click += OnClearTextButtonClick;        }        base.OnApplyTemplate();    }    private void OnClearTextButtonClick(object sender, RoutedEventArgs e)    {        Text = "";    }    public static readonly DependencyProperty ShowClearButtonProperty = DependencyProperty.Register(nameof(ShowClearButton), typeof(bool),                                                                    typeof(PlaceholderComboBox), new PropertyMetadata(true));    public bool ShowClearButton    {        get { return (bool)GetValue(ShowClearButtonProperty); }        set { SetValue(ShowClearButtonProperty, value); }    }    public static readonly DependencyProperty PlaceHolderProperty = DependencyProperty.Register(nameof(PlaceHolder), typeof(string),                                                                     typeof(PlaceholderComboBox), new PropertyMetadata("Placeholder"));    public string PlaceHolder    {        get { return (string)GetValue(PlaceHolderProperty); }        set { SetValue(PlaceHolderProperty, value); }    }    public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.Register(nameof(CornerRadius), typeof(CornerRadius),        typeof(PlaceholderComboBox), new PropertyMetadata(new CornerRadius(0, 0, 0, 0)));    public CornerRadius CornerRadius    {        get { return (CornerRadius)GetValue(CornerRadiusProperty); }        set { SetValue(CornerRadiusProperty, value); }    }}


converter:

public class BoolOppositeConverter : IValueConverter{    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)    {        if (null == value)        {            return false;        }        bool bv = (bool)value;        return !bv;    }    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)    {        throw new NotImplementedException();    }}

public class PlaceholderFontSizeConverter : IValueConverter{    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)    {        double v = (double)value;        return (v * 3.5) / 5.0;    }    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)    {        throw new NotImplementedException();    }}

public class ImageTextBoxMarginLeftConverter : IValueConverter{    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)    {        if (value is double)        {            double v = (double)value;            if (null != parameter)            {                return v * double.Parse(parameter.ToString());            }            return v * 2.0 / 5.0;        }        return 0;    }    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)    {        throw new NotImplementedException();    }}

public class BoolOppositeConverter : IValueConverter{    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)    {        if (null == value)        {            return false;        }        bool bv = (bool)value;        return !bv;    }    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)    {        throw new NotImplementedException();    }}



使用:

<control:PlaceholderComboBox Width="300" Height="45" FontSize="30"                                ShowClearButton="False"                                PlaceHolder="请选择/输入"                                IsEditable="False"                                CornerRadius="0">    <ComboBoxItem>11111111111</ComboBoxItem>    <ComboBoxItem>22222222222</ComboBoxItem>    <ComboBoxItem>3333333333333</ComboBoxItem>    <ComboBoxItem>4444444444444444444444444</ComboBoxItem></control:PlaceholderComboBox><control:PlaceholderComboBox Width="300" Height="45" FontSize="30" Margin="5"                                ShowClearButton="True"                                PlaceHolder="请选择/输入"                                IsEditable="True"                                CornerRadius="0">    <ComboBoxItem>aaaaaaaaaaaaa</ComboBoxItem>    <ComboBoxItem>bbbbbbbbbbbbbb</ComboBoxItem>    <ComboBoxItem>ccccccc</ComboBoxItem>    <ComboBoxItem>ddddddddddddddddd</ComboBoxItem></control:PlaceholderComboBox>