65.9K
CodeProject 正在变化。 阅读更多。
Home

Silverlight 和 WPF 的可空 ComboBox

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.50/5 (3投票s)

2011年3月30日

CPOL

1分钟阅读

viewsIcon

31423

downloadIcon

977

这篇文章描述了一种简单易用的方法,通过使用附加属性和 ComboBox 样式来改变 Silverlight 或 WPF ComboBox 的当前行为。

引言

这篇文章描述了一种简单易用的方法,通过使用附加属性和 ComboBox 样式来改变 Silverlight 或 WPF ComboBox 的当前行为。

这里 是 Silverlight 版本的实时示例。

您需要做的就是将 IsNullable 属性设置为 True,应用于您想要具有此行为的 ComboBox

<ComboBox ItemsSource="{Binding Source={StaticResource ViewModel}, Path=Actors}"
          library:Combobox.IsNullable="True" />

使用代码

首先,您需要更改默认的 ComboBox 样式,以便它包含 X 按钮。 您可以在 这里 找到 Silverlight 的默认样式,在 这里 找到 WPF 的默认样式。 您需要对 ComboBoxTemplate 属性进行以下更改

Silverlight ComboBox
<ContentPresenter x:Name="ContentPresenter" Margin="{TemplateBinding Padding}"  
        HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
        VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
    <TextBlock Text=" " />
</ContentPresenter>
<Button x:Name="PART_ClearButton" Visibility="Collapsed" 
    HorizontalAlignment="Right" Margin="0,0,20,0">
    <Path Data="M0,0 L1.6,0 L3,1.56 L4.4,0 L6,0 L3.8,2.5 L6,5 L4.4,5 L3,
                3.49 L1.59,5 L-4.2E-09,5 L2.18,2.5 z" 
      Fill="#CC111111" Height="5" 
      Stretch="Fill" Width="7"/>
</Button>
WPF ComboBox
<TextBox x:Name="PART_EditableTextBox" Style="{x:Null}"
        Template="{StaticResource ComboBoxTextBox}"
        HorizontalAlignment="Left"
        VerticalAlignment="Bottom"
        Margin="3,3,23,3"
        Focusable="True"
        Background="Transparent"
        Visibility="Hidden"
        IsReadOnly="{TemplateBinding IsReadOnly}" />
<Button x:Name="PART_ClearButton" 
        Visibility="Collapsed" 
        HorizontalAlignment="Right" 
        Margin="0,0,22,0">
    <Path Data="M0,0 L1.6,0 L3,1.56 L4.4,0 L6,0 L3.8,2.5 L6,5 L4.4,
                5 L3,3.49 L1.59,5 L-4.2E-09,5 L2.18,2.5 z" 
      Fill="#CC111111" Height="5" 
      Stretch="Fill" Width="7"/>
</Button>

完成这些更改后,您需要创建 IsNullable 附加属性,它将完成所有工作。 当此属性设置为 ComboBox 上的 True 时,它将启用可空功能。

可空功能是通过使用这两个函数获得的

private static void ApplyIsNullable(ComboBox comboBox)
{
    var isNullable = GetIsNullable(comboBox);
    var clearButton = (Button)GetClearButton(comboBox);
    if (clearButton != null)
    {
        clearButton.Click -= clearButton_Click;
        clearButton.Click += clearButton_Click;

        if (isNullable && comboBox.SelectedIndex != -1)
        {
            clearButton.Visibility = Visibility.Visible;
        }
        else
        {
            clearButton.Visibility = Visibility.Collapsed;
        }
    }
}
 
private static void clearButton_Click(object sender, RoutedEventArgs e)
{
    var clearButton = (Button)sender;
    var parent = VisualTreeHelper.GetParent(clearButton);

    while (!(parent is ComboBox))
    {
        parent = VisualTreeHelper.GetParent(parent);
    }

    var comboBox = (ComboBox)parent;
    //clear the selection
    comboBox.SelectedIndex = -1;
}

ApplyIsNullable 函数刷新 X 按钮的状态,并在 ComboBox 的选择发生更改时调用。 clearButton_Click 函数清除 ComboBox 的选择,并在有人单击 X 按钮时调用。

在我们完成之前,让我们通过使用此自定义按钮样式添加 MouseOver 动画来改善 X 按钮的外观

<Style x:Key="ClearSelectionButtonStyle" TargetType="Button">
    <Setter Property="Background" Value="#FF3C688D"/>
    <Setter Property="BorderBrush" Value="#FF617584"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="Width" Value="15"/>
    <Setter Property="Height" Value="15"/>
    <Setter Property="Padding" Value="0"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Grid Background="Transparent">
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal"/>
                            <VisualState x:Name="MouseOver">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Duration="0" 
                                          Storyboard.TargetProperty="(UIElement.Visibility)" 
                                          Storyboard.TargetName="MouseOverElement">
                                        <DiscreteObjectKeyFrame KeyTime="0">
                                            <DiscreteObjectKeyFrame.Value>
                                                <Visibility>Visible</Visibility>
                                            </DiscreteObjectKeyFrame.Value>
                                        </DiscreteObjectKeyFrame>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Pressed">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Duration="0" 
                                           Storyboard.TargetProperty="(UIElement.Visibility)" 
                                           Storyboard.TargetName="MouseOverElement">
                                        <DiscreteObjectKeyFrame KeyTime="0">
                                            <DiscreteObjectKeyFrame.Value>
                                                <Visibility>Visible</Visibility>
                                            </DiscreteObjectKeyFrame.Value>
                                        </DiscreteObjectKeyFrame>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Disabled"/>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="FocusStates">
                            <VisualState x:Name="Focused"/>
                            <VisualState x:Name="Unfocused"/>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <Border x:Name="MouseOverElement" 
                        BorderThickness="{TemplateBinding BorderThickness}" 
                        Background="#FFC8E4ED" BorderBrush="#FF3F6A8E" 
                        Visibility="Collapsed"/>
                    <ContentPresenter x:Name="contentPresenter" 
                      ContentTemplate="{TemplateBinding ContentTemplate}" 
                      Content="{TemplateBinding Content}" 
                      HorizontalAlignment="Center" 
                      Margin="{TemplateBinding Padding}" 
                      VerticalAlignment="Center"/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

就这样了!:)

历史

  • 版本 1。
© . All rights reserved.