寻找一个带有复选框的WPF组合框

36

我的谷歌搜索无果。有人听说过WPF中类似的控件吗?我正在尝试让它看起来像这样(winforms截图)。

4个回答

65

您可以通过设置组合框的DataTemplate来自行完成此操作。这篇文章为您展示了如何在列表框中实现,但原理相同。


或许这篇文章更适合您所需,只需将项目模板的第一列设置为复选框并将其绑定到商业对象上的布尔值即可。

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

4
如果您想创建一个可重复使用的控件,而又不想在业务对象中添加IsSelected属性,该怎么办? - Kevin Berridge
1
你可以创建一个继承自Combobox的新自定义控件,并修改控件的模板,将弹出窗口中的控件替换为包含复选框的列表。在控件中监听复选框的Checked事件,并维护一个已选项目列表,可以通过属性公开。 - Martin Harris
1
它应该是<CheckBox IsChecked="{Binding IsSelected}" Width="20" />,不是吗? - Philippe
是的,应该是IsChecked。Checked是一个事件。 - alimbada
@Philippe,alimbada - 谢谢您。已更正。 - Martin Harris
@MartinHarris 所有这些链接都已经失效了。 - Luke101

24

这是我的下拉框。我使用了Martin Harris的代码以及来自此链接的代码(当WPF ComboBox的选择为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;
    }
}

这里有两个处理程序——一个用于处理复选框的点击事件,另一个用于生成下拉框的文本。

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! - Ignacio Soler Garcia
3
在我的看法中,模板中的StackPanel和TextBlock是多余的,可以将复选框的Content属性直接绑定到ObjectData。 - Taras
尽管这个解决方案有点笨拙(需要两个不同的、堆叠的控件),但它的效果非常好。被接受的答案只是让你入门,而且还不完整。其他解决方案涉及修改ComboBox的模板或创建自定义控件,更加复杂。 - OfficeAddinDev
请解释如何将值作为泛型添加到ObservableCollection<SelectableObject<tblObject>>中。 - Harmi
如果你想绑定对象的任何属性,则绑定表达式必须为{Binding ObjectData.PropertyName} - Nilesh Thakkar

11
尝试使用Extended WPF Toolkit中的CheckComboBox。对我来说,主要优点是有两个绑定列表:
  • 所有可供选择的项目
  • 只有已选择的项目
我认为这种方法更实用。此外,您可以指定您要绑定的集合的valuedisplay成员。
如果您不想使用其他控件与CheckComboBox一起使用,您可以获取其source code,这很简单(还需要带上Selector class)。

6

带有复选框的组合框

<ComboBox Height="16" Width="15">
    <CheckBox Content="First Checkbox" />
    <CheckBox Content="Second Checkbox" />
    <CheckBox Content="Third Checkbox" />
    <TextBlock Text="Some Text" />
</ComboBox>

提供的答案令我意外地没能解决问题,我试了许多变化,但一直收到有关复选框不是组合框一部分以及数据上下文似乎已损坏的错误消息。
最终,我无需执行任何涉及数据模板或任何代码后台的操作,我的绑定正常工作(示例中未显示)。
我必须说,在阅读了所有答案后,我对这个问题轻松解决感到满意。 带有复选框的组合框

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接