Silverlight 和 WPF 的可空 ComboBox






4.50/5 (3投票s)
这篇文章描述了一种简单易用的方法,通过使用附加属性和 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 的默认样式。 您需要对 ComboBox
的 Template
属性进行以下更改
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。