2009-07-27 9 views
28

Supposons que nous ayons une liaison DataSource à une collection de la base de données. Il n'y a pas d'article nul bien sûr. Comment ajouter un élément vide dans une zone de liste déroulante, de sorte qu'au premier utilisateur de chargement verrait une chaîne vide. Je ne veux pas ajouter un objet factice/vide dans la collection. Optimalement dans XAML. Des propositions?ComboBox avec élément vide?

+3

Prenez garde, que la solution fournie ne fonctionne pas avec la liaison. – Cartesius00

+2

J'ai trouvé un moyen de contourner le problème de liaison voir ce post: http://stackoverflow.com/questions/6446699/how-do-you-bind-a-collectioncontainer-to-a-collection-in-a-view-model – Frinavale

Répondre

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> 

EDIT

Comme @surfen mentionné dans le commentaire, BindingProxy est solution pour le problème de liaison

+0

OK merveilleux. Mais comment rendre le premier élément non sélectionnable? Seuls les éléments de source de données peuvent être sélectionnés. –

+2

Voir le message édité, il vous suffit d'ajouter IsEnabled = "False" Foreground = "Black" pour les propriétés des articles –

+0

OK désolé je n'ai pas remarqué que les propriétés. Je vous remercie ! –

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

Pourriez-vous expliquer pourquoi cette travaux? – nikaltipar

+0

Ceci fonctionne à cause d'un événement souris –

1

Pour la liaison sur l'objet MVVM:

     <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> 

Et pour la liaison sur:

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

Et le convertisseur générique:

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; 
    } 
} 

Juste important de déclarer la SelectedValuePath dans combobox. :-)

0

Essayez la boîte combo Mahapps.

xmlns: contrôle = "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

Questions connexes