【问题标题】:ComboBox with empty item?带有空项目的组合框?
【发布时间】:2010-11-14 09:00:58
【问题描述】:

假设我们有一个 DataSource 绑定到数据库中的一个集合。当然没有空项目。如何将 void 项添加到 ComboBox 中,以便在第一次加载时用户会看到一个空字符串。我不想在 Collection 中添加一个 dummy/void 对象。 最好在 XAML 中。有什么建议吗?

【问题讨论】:

标签: wpf combobox


【解决方案1】:

试试 Mahapps 组合框。

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

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

【讨论】:

    【解决方案2】:

    用于绑定 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>
    

    对于绑定:

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

    还有通用转换器:

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

    在组合框中声明 SelectedValuePath 很重要。 :-)

    【讨论】:

      【解决方案3】:
      <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;
              }
          }
      }
      

      【讨论】:

      • 什么是 EmptyModuleComboBox?
      【解决方案4】:
      <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>
      

      编辑

      正如评论中提到的@surfenBindingProxy 是绑定问题的解决方法

      【讨论】:

      • 查看编辑后的帖子,您只需将 IsEnabled="False" Foreground="Black" 添加到项目属性中
      • 我似乎无法让它在 ViewModel 绑定场景中工作......有什么想法吗?
      • 啊...我想通了。 CompositeCollection 不是 Freezable,因此它不适用于绑定。不幸。
      • 我找到了解决 CompositeCollection 问题的方法:stackoverflow.com/questions/6446699/…
      • @surfen,因为您的博客已移动,这是新网址:thomaslevesque.com/2011/03/21/…
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-19
      • 2011-08-05
      相关资源
      最近更新 更多