2016-12-14 205 views
1

我有一个组合框,其中的项目从0到63的整数值。我想添加选择所有选项。我如何选择所有应该选择的项目?选择所有组合框内的复选框Wpf中的组合框项目

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

视图模型:

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

类:

private List<GenericDescription> _Set2CmdList; 

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

视图模型的构造

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

回答

1

你可以用下面的控制, 注意,这不是一个完整的控制,它会给你一个领先地位,(你需要检查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); 
    } 
} 

和通用文件,添加模板组合框和更换下方的线条,

<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> 
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 
    } 
} 
+0

这不起作用 –

+0

你能告诉我什么是详细问题。 – Eldho

+0

我绑定检查所有作为复选框的命令,但是当我选择全选,它不是选择所有和onproperty布尔显示错误 –