在Wpf中的Combobox项目中选择所有复选框

时间:2016-12-14 07:12:24

标签: wpf

我有一个组合框,其中包含0到63个整数值的项目。我想添加select all选项。如果我选择全部它应该选择所有项目,我怎么能这样做?

<DataTemplate x:Key="cmbIndex">
    <CheckBox IsChecked="{Binding Path=IsSelected, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
              Tag="{RelativeSource FindAncestor, AncestorType={x:Type ComboBox}}"
              Content="{Binding Name}" Name="chkbox"
              Click="CheckBox_Click">
    </CheckBox>
</DataTemplate>

<CollectionViewSource x:Key="coll" Source="{Binding Set2CmdList,UpdateSourceTrigger=PropertyChanged}"/>
<ComboBox Grid.Row="0" SelectedIndex="{Binding Set2SelectedIndex}"
          HorizontalAlignment="Left" Margin="80,0,0,0"
          Height="20" VerticalAlignment="Center" Width="60" 
          FontFamily="Calibri" FontSize="12" >

    <ComboBox.ItemsSource>
        <CompositeCollection>
            <!--<ComboBoxItem>
                <CheckBox x:Name="all">Select All</CheckBox>
            </ComboBoxItem>-->
            <CollectionContainer   Collection="{Binding Source={StaticResource coll}}"/>
        </CompositeCollection>
    </ComboBox.ItemsSource>
    <ComboBox.Style>
        <Style TargetType="{x:Type ComboBox}">
            <Setter Property="ItemTemplate" Value="{StaticResource cmbIndex}"/>
        </Style>
    </ComboBox.Style>
</ComboBox>

查看型号:

private List<GenericDescription> _Set2CmdList;

public List<GenericDescription> Set2CmdList
{
    get { return _Set2CmdList; }
    set { _Set2CmdList = value; }
}

viewmodel的构造函数:

_CMDCollection = new ObservableCollection<int>();
_Set2CmdList = new List<GenericDescription>();
_Set2CmdList.Add(new GenericDescription() { Name="Select All",IsSelected=false });

for (int i = 0; i < 64; i++)
{
    _CMDCollection.Add(i);
    _Set2CmdList.Add(new GenericDescription()
    {
        Name = i.ToString(),
        IsSelected = false
    });
}

类别:

public class GenericDescription
{
    private string _Name;

    public string Name
    {
        get { return _Name; }
        set { _Name = value;}
    }

    private bool _IsSelected;

    public bool IsSelected
    {
        get { return _IsSelected; }
        set { _IsSelected = value; }
    }
}

2 个答案:

答案 0 :(得分:1)

这样的方法会将您的所有项目分配到选定的

将此选中所有方法作为命令绑定到您的复选框。

public void CheckAll()
{

   foreach(var item in Set2CmdList)
   {
       item.IsSelected = true;
   }
}

public bool IsSelected
{
    get { return _IsSelected; }
    set 
    {
      _IsSelected = value;
      OnPropertyChanged(); //See interface INotifyProeprtyChanged interface
    }
}

答案 1 :(得分:1)

你可以尝试以下控制, 注意,这不是一个完整的控件,它会给你一个headstart,(你需要检查NRE和其他场景)

 public class MultiComboBox : ComboBox
{
    static MultiComboBox()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(MultiComboBox), new FrameworkPropertyMetadata(typeof(MultiComboBox)));
        EventManager.RegisterClassHandler(typeof(MultiComboBox), Selector.SelectedEvent, new RoutedEventHandler(OnSelected));
        EventManager.RegisterClassHandler(typeof(MultiComboBox), Selector.UnselectedEvent, new RoutedEventHandler(OnUnselected));
    }

    CheckBox PART_SelectAll;
    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        PART_SelectAll = base.GetTemplateChild("PART_SelectAll") as CheckBox;
        PART_SelectAll.Checked += PART_SelectAll_Checked;
        PART_SelectAll.Unchecked += PART_SelectAll_UnChecked;
    }

    private void PART_SelectAll_Checked(object sender, RoutedEventArgs e)
    {
        ProcessSelection(PART_SelectAll.IsChecked.Value);
    }
    private void PART_SelectAll_UnChecked(object sender, RoutedEventArgs e)
    {
        ProcessSelection(PART_SelectAll.IsChecked.Value);

    }

    internal void NotifySelectedItems(object item, bool isSelected)
    {

        if (SelectedItems == null)
            SelectedItems = new List<Object>();
        if (SelectedItems != null)
        {
            if (isSelected)
                SelectedItems.Add((item as MultiComboBoxItem).DataContext);
            else
                SelectedItems.Remove((item as MultiComboBoxItem).DataContext);
        }
    }
    internal void SetSelectedItem(object item)
    {
        SetValue(SelectedItemProperty, item);
    }
    private void ProcessSelection(bool select)
    {
        foreach (var item in this.Items)
        {
            if(this.ItemsSource != null)
            {
                var cItem = this.ItemContainerGenerator.ContainerFromItem(item) as MultiComboBoxItem;
                if(cItem != null)
                {
                    cItem.SetValue(ComboBoxItem.IsSelectedProperty, select);
                }
            }
        }
    }

    private static void OnSelected(object sender, RoutedEventArgs e)
    {
        e.Handled = true;
    }
    private static void OnUnselected(object sender, RoutedEventArgs e)
    {
        e.Handled = true;
    }

    public MultiComboBox()
    {

    }

    public IList SelectedItems
    {
        get { return (IList)GetValue(SelectedItemsProperty); }
        set { SetValue(SelectedItemsProperty, value); }
    }

    // Using a DependencyProperty as the backing store for SelectedItems.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty SelectedItemsProperty =
        DependencyProperty.Register("SelectedItems", typeof(IList), typeof(MultiComboBox), new PropertyMetadata(null));

    protected override DependencyObject GetContainerForItemOverride()
    {
        var multiComboItem = new MultiComboBoxItem();
        multiComboItem.ParentComboBox = this;
        return multiComboItem;
    }

    protected override void OnSelectionChanged(SelectionChangedEventArgs e)
    {
        base.OnSelectionChanged(e);
    }
}

 public class MultiComboBoxItem : ComboBoxItem
{
    static MultiComboBoxItem()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(MultiComboBoxItem), new FrameworkPropertyMetadata(typeof(MultiComboBoxItem)));
    }

    public MultiComboBox ParentComboBox { get; set; }

    protected override void OnSelected(RoutedEventArgs e)
    {
        ParentComboBox.NotifySelectedItems(this, true);
        base.OnSelected(e);
        if (ParentComboBox.SelectedItem == null)
            ParentComboBox.SetValue(ComboBox.SelectedItemProperty, this.DataContext);
    }

    protected override void OnUnselected(RoutedEventArgs e)
    {
        ParentComboBox.NotifySelectedItems(this, false);
        base.OnUnselected(e);
        if (ParentComboBox.SelectedItems.Count == 0 || this.DataContext == ParentComboBox.SelectedItem)
            ParentComboBox.ClearValue(ComboBox.SelectedItemProperty);
    }
}

并在通用文件中,为ComboBox添加模板并替换以下行

<ControlTemplate x:Key="ComboBoxTemplate" TargetType="{x:Type local:MultiComboBox}">
    <Grid x:Name="templateRoot" SnapsToDevicePixels="true">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="0" MinWidth="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" />
        </Grid.ColumnDefinitions>
        <Popup x:Name="PART_Popup"
               Grid.ColumnSpan="2"
               Margin="1"
               AllowsTransparency="true"
               IsOpen="{Binding IsDropDownOpen,
                                Mode=TwoWay,
                                RelativeSource={RelativeSource TemplatedParent}}"
               Placement="Bottom"
               PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}">
            <Border x:Name="dropDownBorder"
                    Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
                    BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}"
                    BorderThickness="1">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <CheckBox Grid.Row="0" Content="Select All" Name="PART_SelectAll"/>
                    <ScrollViewer Grid.Row="1" x:Name="DropDownScrollViewer">
                        <Grid x:Name="grid" RenderOptions.ClearTypeHint="Enabled">
                            <Canvas x:Name="canvas"
                                Width="0"
                                Height="0"
                                HorizontalAlignment="Left"
                                VerticalAlignment="Top">
                                <Rectangle x:Name="opaqueRect"
                                       Width="{Binding ActualWidth,
                                                       ElementName=dropDownBorder}"
                                       Height="{Binding ActualHeight,
                                                        ElementName=dropDownBorder}"
                                       Fill="{Binding Background,
                                                      ElementName=dropDownBorder}" />
                            </Canvas>
                            <ItemsPresenter x:Name="ItemsPresenter"
                                        KeyboardNavigation.DirectionalNavigation="Contained"
                                        SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                        </Grid>
                    </ScrollViewer>

                </Grid>
            </Border>
        </Popup>
        <ToggleButton x:Name="toggleButton"
                      Grid.ColumnSpan="2"
                      Background="{TemplateBinding Background}"
                      BorderBrush="{TemplateBinding BorderBrush}"
                      BorderThickness="{TemplateBinding BorderThickness}"
                      IsChecked="{Binding IsDropDownOpen,
                                          Mode=TwoWay,
                                          RelativeSource={RelativeSource TemplatedParent}}"
                      Style="{StaticResource ComboBoxToggleButton}" />
        <ContentPresenter x:Name="contentPresenter"
                          Margin="{TemplateBinding Padding}"
                          HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                          VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                          Content="{TemplateBinding SelectionBoxItem}"
                          ContentStringFormat="{TemplateBinding SelectionBoxItemStringFormat}"
                          ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
                          ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
                          IsHitTestVisible="false"
                          SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
    </Grid>
    <ControlTemplate.Triggers>
        <Trigger SourceName="PART_Popup" Property="HasDropShadow" Value="true" />
        <Trigger Property="HasItems" Value="false">
            <Setter TargetName="dropDownBorder" Property="Height" Value="95" />
        </Trigger>
        <MultiTrigger>
            <MultiTrigger.Conditions>
                <Condition Property="IsGrouping" Value="true" />
                <Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="false" />
            </MultiTrigger.Conditions>
            <Setter Property="ScrollViewer.CanContentScroll" Value="false" />
        </MultiTrigger>
        <Trigger SourceName="DropDownScrollViewer" Property="ScrollViewer.CanContentScroll" Value="false">
            <Setter TargetName="opaqueRect" Property="Canvas.Top" Value="{Binding VerticalOffset, ElementName=DropDownScrollViewer}" />
            <Setter TargetName="opaqueRect" Property="Canvas.Left" Value="{Binding HorizontalOffset, ElementName=DropDownScrollViewer}" />
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>