When binding a ComboBox in WPF, you don’t have access to select a null value. There is several ways to allow ComboBox to select a null value:
- By Code: You can create a list of items and add a null item (not a null value but and item instance representing the null value). This is not reusable.
- By using a Converter: This is a bit more reusable but is not the best for scenario that already needs a converter. Also, this method require a convert from and a convert back of the value.
- By using an Attached Property: To me, this seems the ideal way (unless it is implemented directly by the ComboBox) to manage null value and this will be the technique describe here.
Here is how to create the Attached property:
public static class ComboUtil
{
private static readonly CommandBinding DeleteCommandBinding = new CommandBinding(ApplicationCommands.Delete, HandleExecuteDeleteCommand);
private static void HandleExecuteDeleteCommand(object sender, ExecutedRoutedEventArgs e)
{
var combo = e.Source as ComboBox;
if (combo != null)
combo.SelectedIndex = -1;
}
#region AllowNull Property
public static bool GetAllowNull(ComboBox combo)
{
if (combo == null)
throw new ArgumentNullException("combo");
return (bool)combo.GetValue(AllowNullProperty);
}
public static void SetAllowNull(ComboBox combo, bool value)
{
if (combo == null)
throw new ArgumentNullException("combo");
combo.SetValue(AllowNullProperty, value);
}
public static readonly DependencyProperty AllowNullProperty =
DependencyProperty.RegisterAttached(
"AllowNull",
typeof(bool),
typeof(ComboUtil),
new UIPropertyMetadata(HandleAllowNullPropertyChanged));
private static void HandleAllowNullPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
var combo = (ComboBox)o;
if (true.Equals(e.NewValue))
{
if (!combo.CommandBindings.Contains(DeleteCommandBinding))
combo.CommandBindings.Add(DeleteCommandBinding);
}
else
{
combo.CommandBindings.Remove(DeleteCommandBinding);
}
}
#endregion
}
By using the above code, you will now be able to create a nullable comboBox by xaml only:
<ComboBox local:ComboUtil.AllowNull="true">
<ComboBoxItem>Hello</ComboBoxItem>
<ComboBoxItem>Hi</ComboBoxItem>
</ComboBox>
and reset the combo by hitting the <DELETE> key when the ComboBox has the input focus.
Happy WPF programming!
Dany