2009-07-27 19 views
28

Supongamos que tenemos un enlace de DataSource a una colección de la base de datos. No hay un elemento nulo, por supuesto. Cómo agregar un elemento vacío en un ComboBox, para que al primer usuario de carga vea una cadena vacía. No quiero agregar un objeto ficticio/vacío a la Colección. Óptimamente en XAML. ¿Alguna propuesta?ComboBox con el artículo vacío?

+3

Ten cuidado, que la solución proporcionada no funciona con la unión. – Cartesius00

+2

Encontré una forma de resolver el problema vinculante. Ver esta publicación: http://stackoverflow.com/questions/6446699/how-do-you-bind-a-collectioncontainer-to-a-collection-in-a-view-model – Frinavale

Respuesta

36
<ComboBox Name="myComboBox" Width="200" Background="White">  
    <ComboBox.ItemsSource>  
     <CompositeCollection> 
      <ComboBoxItem IsEnabled="False" Foreground="Black">Select Item</ComboBoxItem> 
      <CollectionContainer Collection="{Binding Source={StaticResource DataKey}}" />  
     </CompositeCollection> 
    </ComboBox.ItemsSource> 
</ComboBox> 

EDITAR

Como @surfen mencionado en el comentario, BindingProxy es solución para el problema de unión

+0

OK maravilloso. Pero, ¿cómo hacer que el primer elemento no sea seleccionable? Solo se pueden seleccionar elementos de origen de datos. –

+2

Ver la publicación editada, solo necesita agregar IsEnabled = "False" Foreground = "Black" a las propiedades de los elementos –

+0

OK lo siento, no me di cuenta de esas propiedades. Gracias ! –

2
<UserControl.Resources> 
    <CollectionViewSource x:Key="Modules" Source="{Binding Path=Modules}" /> 
</UserControl.Resources> 

<abv:ComboBox SelectedIndex="0" IsNullable="True" 
    SelectedItem="{Binding Path=SelectedModule, Mode=TwoWay}"> 
    <abv:ComboBox.ItemsSource> 
     <CompositeCollection> 
      <ComboBoxItem Content="{DynamicResource EmptyModuleComboBox}"/> 
      <CollectionContainer Collection="{Binding Source={StaticResource Modules}}" /> 
     </CompositeCollection> 
    </abv:ComboBox.ItemsSource> 
</abv:ComboBox> 

public class ComboBox : System.Windows.Controls.ComboBox 
{ 
    public static readonly DependencyProperty IsNullableProperty = 
     DependencyProperty.Register("IsNullable", typeof(bool), typeof(ComboBox)); 

    public bool IsNullable 
    { 
     get { return (bool)GetValue(IsNullableProperty); } 
     set { SetValue(IsNullableProperty, value); } 
    } 

    public ComboBox() 
    { 
     Loaded += ComboBox_Loaded; 
    } 

    void ComboBox_Loaded(object sender, RoutedEventArgs e) 
    { 

     if (IsNullable) 
     { 
      this.ItemContainerStyle = new Style(); 

      this.ItemContainerStyle.Setters.Add(new EventSetter() 
      { 
       Event = ComboBoxItem.PreviewMouseUpEvent, 
       Handler = new MouseButtonEventHandler(cmbItem_PreviewMouseUp) 
      }); 
     } 
    } 

    public void cmbItem_PreviewMouseUp(object sender, MouseButtonEventArgs e) 
    { 
     if (Items.IndexOf(sender as ComboBoxItem) == 0) 
     { 
      SelectedItem = null; 
     } 
    } 
} 
+1

¿Podría explicar por qué esto ¿trabajos? – nikaltipar

+0

Esto funciona porque se suscribe al evento de mouse up –

1

Para la unión de MVVM objeto:

     <ComboBox Name="cbbFiltres" SelectedItem="{Binding ElmtInfo, Mode=TwoWay}" Height="26" MinWidth="90" SelectedIndex="0" SelectedValuePath="Id"> 
         <ComboBox.Resources> 
          <CollectionViewSource x:Key="cvsFiltres" Source="{Binding Elmts.items}"/> 
         </ComboBox.Resources> 
         <ComboBox.ItemsSource> 
          <CompositeCollection> 
           <model:tblFiltreChamps Desc="{x:Static resx:resMain.enumAucun}" Id="0"/> 
           <CollectionContainer Collection="{Binding Source={StaticResource cvsFiltres}}" /> 
          </CompositeCollection> 
         </ComboBox.ItemsSource> 
        </ComboBox> 

Y para la unión en:

<Label Visibility="{Binding Path=SelectedValue, ElementName=cbbFiltres, Converter={StaticResource NullToVisibility}}" /> 

Y el conversor genérico:

public class ConvNullToVisibility : IValueConverter { 
    /// <summary>Convertisseur pour le Get.</summary> 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { 
     if (DesignerProperties.GetIsInDesignMode(new DependencyObject())) return Visibility.Visible; // Pour annuler l'effet dans le designer: http://stackoverflow.com/questions/33401900/wpf-detect-design-mode-in-a-converter 
     return ((value == null) || (string.IsNullOrEmpty(value.ToString())) || (value.ToString() == "0")) ? Visibility.Collapsed : Visibility.Visible; 
    } 

    /// <summary>Convertisseur inverse, pour le Set (Binding).</summary> 
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { 
     if (value is Visibility) { 
      return (((Visibility)value) == Visibility.Visible) ? true : false; 
     } else return false; 
    } 
} 

sólo importante para declarar la SelectedValuePath en cuadro combinado. :-)

0

Pruebe el cuadro combinado de Mahapps.

xmlns: controles = "http://metro.mahapps.com/winfx/xaml/controls"

<ComboBox x:Name="bars" **controls:TextBoxHelper.ClearTextButton="True"** 
       DisplayMemberPath="Name" 
       Height="21" 
       SelectedItem="{Binding Bar}"/> 

Combo Box View