【问题标题】:Looking for a WPF ComboBox with checkboxes寻找带有复选框的 WPF ComboBox
【发布时间】:2010-10-25 22:41:06
【问题描述】:

我的谷歌技能让我失望。任何人都听说过类似 WPF 的控件。我试图让它看起来像这样(winforms screenshot)。

【问题讨论】:

    标签: wpf combobox checkedlistbox


    【解决方案1】:

    Extended WPF Toolkit 尝试CheckComboBox。 对我来说主要优势是有两个绑定列表:

    • 所有可供选择的项目
    • 刚刚选择的项目

    我发现这种方法更实用。此外,您可以指定要绑定的集合的 valuedisplay 成员。

    如果你不想用CheckComboBox带一堆其他控件,你可以得到它的source code,它很简单(需要带Selector class)。

    【讨论】:

      【解决方案2】:

      这是我的组合框。我使用 Martin Harris 代码和来自此链接的代码 Can a WPF ComboBox display alternative text when its selection is null?

      <ComboBox Name="cbObjects" Grid.Column="1" Grid.Row="1" VerticalAlignment="Center" Margin="2,2,6,0" SelectionChanged="OnCbObjectsSelectionChanged" >
          <ComboBox.ItemTemplate>
              <DataTemplate>
                  <StackPanel Orientation="Horizontal">
                      <CheckBox IsChecked="{Binding IsSelected}" Width="20" VerticalAlignment="Center" Checked="OnCbObjectCheckBoxChecked" Unchecked="OnCbObjectCheckBoxChecked" />
                      <TextBlock Text="{Binding ObjectData}" VerticalAlignment="Center" />
                  </StackPanel>
              </DataTemplate>
          </ComboBox.ItemTemplate>
      </ComboBox>
      <TextBlock IsHitTestVisible="False" Name="tbObjects" Text="Выберите объекты..." Grid.Column="1" Grid.Row="1" VerticalAlignment="Center" Margin="6,2,6,0" />
      

      数据源小类:

      public class SelectableObject <T> {
          public bool IsSelected { get; set; }
          public T ObjectData { get; set; }
      
          public SelectableObject(T objectData) {
              ObjectData = objectData;
          }
      
          public SelectableObject(T objectData, bool isSelected) {
              IsSelected = isSelected;
              ObjectData = objectData;
          }
      }
      

      并且有两个处理程序 - 一个用于处理单击的 CheckBox,另一个用于为 ComboBox 形成文本。

      private void OnCbObjectCheckBoxChecked(object sender, RoutedEventArgs e) {
          StringBuilder sb = new StringBuilder();
          foreach (SelectableObject<tblObject> cbObject in cbObjects.Items) 
          {
              if (cbObject.IsSelected)
                  sb.AppendFormat("{0}, ", cbObject.ObjectData.Description);
          }
          tbObjects.Text = sb.ToString().Trim().TrimEnd(',');
      }
      
      private void OnCbObjectsSelectionChanged(object sender, SelectionChangedEventArgs e) {
          ComboBox comboBox = (ComboBox)sender;
          comboBox.SelectedItem = null;
      }
      

      对于 ComboBox.ItemsSource 我使用

      ObservableCollection<SelectableObject<tblObject>> 
      

      其中 tblObject 是我的对象的类型,我想在 ComboBox 中显示它的列表。

      我希望这段代码对某人有用!

      【讨论】:

      • 我喜欢 SelectableObject 的想法。 +1!
      • imho StackPanel 和模板中的 TextBlock 是多余的,可以将复选框的 Content 属性绑定到 ObjectData..
      • 这个解决方案运行得非常好,尽管有点笨拙(它需要两个不同的堆叠控件)。接受的答案只会让你开始并且不完整。其他解决方案涉及修改 ComboBox 的模板或创建自定义控件,并且要复杂得多。
      • 请解释如何将 ObservableCollection> 中的值添加为泛型。
      • 如果要绑定对象的任何属性,则绑定表达式必须是 {Binding ObjectData.PropertyName}
      【解决方案3】:

      您可以通过设置组合框的 DataTemplate 自行完成。 This article 向您展示了如何 - 对于列表框,但原理是相同的。


      另一篇文章here 可能更适合您尝试做的事情,只需将项目模板的第一列设置为复选框并将其绑定到业务对象上的布尔值。

      <ComboBox.ItemTemplate>
          <DataTemplate>
              <StackPanel Orientation="Horizontal">
                  <CheckBox IsChecked="{Binding IsSelected}"
                             Width="20" />
                  <TextBlock Text="{Binding DayOfWeek}"
                             Width="100" />
              </StackPanel>
          </DataTemplate>
      </ComboBox.ItemTemplate>
      

      【讨论】:

      • 如果您想创建一个可重用的控件并且不想将 IsSelected 添加到您的业务对象中怎么办?
      • 您可以创建一个从 Combobox 继承的新自定义控件,并更改控件的模板以将弹出窗口中的控件替换为包含复选框的列表。监听控件中的复选框 Checked 事件,并维护可以通过属性公开的选中项列表。
      • 应该是,不是吗?
      • 是的,应该是 IsChecked。检查是一个事件。
      • @Philippe,alimbada - 谢谢。已更正。
      猜你喜欢
      • 2016-12-18
      • 1970-01-01
      • 2019-02-22
      • 2013-06-11
      • 1970-01-01
      • 2016-11-26
      • 1970-01-01
      • 2013-06-15
      • 1970-01-01
      相关资源
      最近更新 更多