2015-01-03 7 views
3

У меня есть combobox, и он заполнен связкой флажков. Я хочу, чтобы пользователь мог щелкнуть несколько раз, прежде чем комбобокс закрывается (или закрывается самим пользователем). Проблемы прямо сейчас в том, что каждый раз, когда нажимается флажок, combobox закрывается, заставляя пользователя, который хочет выбрать несколько вариантов, повторно открыть его несколько раз.CheckComboBox: Как предотвратить закрытие combobox после выбора?

Я нашел другие вопросы по тому же вопросу, но они применимы к Silverlight, Qt и т. Д., Сравнивая теги.

Я пробовал установить StayOpenOnEdit, но это не помогло. Насколько я мог видеть, нет никакой собственности для решения моей проблемы. Это создает подозрение, что я могу скрыть не тот компонент вместе.

  1. Как предотвратить автоматическое закрытие выпадающего списка после щелчка по нему?
  2. Есть ли более подходящий компонент для такой задачи, и если да, то как его зовут?

Обратите внимание, что даже если ответ на # 2 «да», мне все еще любопытно № 1 по чисто академическим причинам.

Я играл с кнопкой переключения и списком, как кто-то предложил в сообщении. Тем не менее, это привело только к всегда полностью показанному списку всех флажков с какой-то серой вещью за ней (что я предполагаю, это toggler). Возможно, я сделал что-то менее умное в надбавке.

<ToggleButton HorizontalAlignment="Left" 
       Margin="550,62,0,0" 
       VerticalAlignment="Top" 
       Width="100"> 
    <ListBox x:Name="listBox1" 
      HorizontalAlignment="Left" 
      Height="100" 
      VerticalAlignment="Top" Width="100"> 
    <CheckBox x:Name="checkBox3" Content="CheckBox"/> 
    <CheckBox x:Name="checkBox4" Content="CheckBox"/> 
    </ListBox> 
</ToggleButton> 

Дела в том, чтобы достичь something like this, но она должна быть стандартное управление WPF (каскадные линии всех выбранных элементов хорошо, но не обязательно). Кроме того, я читал жалобы, что привязка и обработка еще не полностью разработаны, и я чувствую себя немного подозрительно.

+0

Это CodeProject кажется, чтобы покрыть ваши потребности довольно хорошо: http://www.codeproject.com/Articles/42133/Multiple-Selection-ComboBox- for-Silverlight (это серебристый свет, но вы можете следовать тем же шагам для wpf) –

+0

Я прочитал его, но меня все еще что-то смущает. Работает ли он с флажками для combobox и listbox? Или он работает с флажками, помещенными в список, который сам по себе помещен в поле со списком? –

ответ

7

Использование Exapander Control вы можете добиться выбора множества элементов без закрытия всплывающего окна после одного выбора.

Для понимания, пожалуйста, запустите этот код отдельно.

XAML

<Window.Resources> 
    <ControlTemplate x:Key="ComboboxToggleButton" TargetType="{x:Type ToggleButton}"> 
     <Grid Background="{Binding Background,RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}"> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition /> 
       <ColumnDefinition Width="35" /> 
      </Grid.ColumnDefinitions> 
      <Border x:Name="Border" Grid.ColumnSpan="2" Background="Transparent" BorderBrush="Black" BorderThickness="{Binding BorderThickness,RelativeSource={RelativeSource TemplatedParent}}"/> 
      <Path x:Name="Arrow" Grid.Column="1" Opacity="1" Stroke="Black" StrokeThickness="1.5" HorizontalAlignment="Center" VerticalAlignment="Center" Data="M 0 0 L 6 6 L 12 0" /> 
      <Path x:Name="Arrow_checked" Opacity="0" Grid.Column="1" Fill="Black" Stroke="Black" StrokeThickness="1" HorizontalAlignment="Center" VerticalAlignment="Center" Data="M 0 0 L 6 6 L 12 0 Z" /> 
      <ContentPresenter TextElement.FontFamily="Segoe Ui Dark" TextElement.FontSize="18" TextElement.Foreground="Black" VerticalAlignment="Center" Grid.Column="0" Margin="10,0,0,0" HorizontalAlignment="Left" RecognizesAccessKey="True" SnapsToDevicePixels="True" /> 
     </Grid> 
     <ControlTemplate.Triggers> 
      <Trigger Property="ToggleButton.IsMouseOver" Value="true"> 
       <Setter TargetName="Border" Property="Background" Value="Gray" /> 
       <Setter TargetName="Border" Property="BorderThickness" Value="1.2" /> 
      </Trigger> 
      <Trigger Property="IsChecked" Value="False"> 
       <Setter Property="Opacity" Value="1" TargetName="Arrow"/> 
       <Setter Property="Opacity" Value="0" TargetName="Arrow_checked"/> 
      </Trigger> 
      <Trigger Property="ToggleButton.IsChecked" Value="true"> 
       <Setter Property="Opacity" Value="0" TargetName="Arrow"/> 
       <Setter Property="Opacity" Value="1" TargetName="Arrow_checked"/> 
      </Trigger> 
      <Trigger Property="IsEnabled" Value="False"> 
       <Setter TargetName="Border" Property="Background" Value="Gray" /> 
       <Setter TargetName="Border" Property="BorderBrush" Value="White" /> 
      </Trigger> 
     </ControlTemplate.Triggers> 
    </ControlTemplate> 

    <Style TargetType="{x:Type Expander}"> 
     <Setter Property="FontFamily" Value="Segoe Ui Dark"></Setter> 
     <Setter Property="HorizontalContentAlignment" Value="Stretch"/> 
     <Setter Property="VerticalContentAlignment" Value="Stretch"/> 
     <Setter Property="MaxHeight" Value="200"></Setter> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type Expander}"> 
        <DockPanel> 
         <ToggleButton x:Name="HeaderSite" Height="35" Background="{TemplateBinding Background}" ContentTemplate="{TemplateBinding HeaderTemplate}" ContentTemplateSelector="{TemplateBinding HeaderTemplateSelector}" Content="{TemplateBinding Header}" DockPanel.Dock="Top" Foreground="Black" FontStyle="{TemplateBinding FontStyle}" FontFamily="Segoe UI Dark" 
        IsChecked="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Template="{StaticResource ComboboxToggleButton}" /> 
         <Border BorderThickness="0,4.5,0,0" BorderBrush="Transparent"> 
          <Border x:Name="bod" BorderBrush="Transparent" SnapsToDevicePixels="True" BorderThickness="1"> 
           <ContentPresenter x:Name="ExpandSite" Focusable="false" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Visibility="Collapsed" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" /> 
          </Border> 
         </Border> 
        </DockPanel> 
        <ControlTemplate.Triggers> 
         <Trigger Property="IsExpanded" Value="true"> 
          <Setter Property="Visibility" TargetName="ExpandSite" Value="Visible"/> 
          <Setter Property="BorderBrush" TargetName="bod" Value="Black"/> 
         </Trigger> 
         <Trigger Property="IsEnabled" Value="false"> 
          <Setter Property="Foreground" Value="Gray"></Setter> 
         </Trigger> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 

    <Style x:Key="itemstyle" TargetType="{x:Type ListBoxItem}"> 
     <Setter Property="SnapsToDevicePixels" Value="true" /> 
     <Setter Property="OverridesDefaultStyle" Value="true" /> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="ListBoxItem"> 
        <Grid x:Name="Border" Height="40" SnapsToDevicePixels="true"> 
         <Grid.Background> 
          <SolidColorBrush Color="Transparent" /> 
         </Grid.Background> 
         <ContentPresenter Name="cmb_name" TextElement.FontFamily="Segoe Ui Dark" TextElement.FontSize="18" TextElement.Foreground="Black" Margin="10,0,0,0" VerticalAlignment="Center"></ContentPresenter> 
        </Grid> 
        <ControlTemplate.Triggers> 
         <Trigger Property="IsMouseOver" Value="True"> 
          <Setter TargetName="Border" Property="Background" Value="Gray"></Setter> 
         </Trigger> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
     <Setter Property="FocusVisualStyle"> 
      <Setter.Value> 
       <Style TargetType="Control"> 
        <Setter Property="Template"> 
         <Setter.Value> 
          <ControlTemplate> 
           <Border BorderBrush="{DynamicResource customBlueBrush}" BorderThickness="1" Margin="1,2,2,2" > 
            <Rectangle Fill="{DynamicResource customBlueBrush}" Opacity="0.1"></Rectangle> 
           </Border> 
          </ControlTemplate> 
         </Setter.Value> 
        </Setter> 
       </Style> 
      </Setter.Value> 
     </Setter> 
    </Style> 

    <Style TargetType="CheckBox" > 
     <Setter Property="SnapsToDevicePixels" Value="True"></Setter> 
     <Setter Property="OverridesDefaultStyle" Value="True"></Setter> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="CheckBox"> 
        <Grid x:Name="ab" Background="Transparent"> 
         <Grid.ColumnDefinitions> 
          <ColumnDefinition Width="30"/> 
          <ColumnDefinition/> 
         </Grid.ColumnDefinitions> 
         <Rectangle VerticalAlignment="Center" Height="20" Width="20" Fill="White" HorizontalAlignment="Left"></Rectangle> 
         <Grid x:Name="checkGrid" VerticalAlignment="Center" Height="20" Width="20" Background="Black" HorizontalAlignment="Left"> 
          <Viewbox Height="13" Width="13"> 
           <Path x:Name="Check" SnapsToDevicePixels="True" UseLayoutRounding="True" Width="18.7969" Height="16.3094" Canvas.Left="0" Canvas.Top="1.52588e-005" Stretch="Fill" Fill="White" Data="F1 M 0.731262,8.75935L 0.106262,8.08437C 0.0354614,7.9948 0,7.8979 0,7.79375C 0,7.66875 0.0479736,7.5573 0.143799,7.45937L 1.94067,5.77187C 2.02606,5.69893 2.12708,5.66249 2.24377,5.66249C 2.30212,5.66249 2.36096,5.67397 2.42035,5.69685C 2.47974,5.71977 2.52814,5.75417 2.56567,5.79997L 7.5188,11.1406L 16.0438,0.165604C 16.1417,0.055191 16.2584,1.52588e-005 16.3938,1.52588e-005C 16.4979,1.52588e-005 16.5896,0.0322723 16.6688,0.0968475L 18.6313,1.60939C 18.6709,1.64272 18.7084,1.69011 18.7438,1.75154C 18.7792,1.813 18.7969,1.8698 18.7969,1.92189C 18.7969,2.03435 18.7646,2.1385 18.7,2.23439L 7.74377,16.3094L 0.731262,8.75935 Z " /> 
          </Viewbox> 
         </Grid> 
         <Grid Background="Transparent" Grid.Column="1" IsHitTestVisible="True" HorizontalAlignment="Stretch"> 
          <TextBlock VerticalAlignment="Center" FontSize="18" FontFamily="Segoe Ui Dark" Foreground="Black" TextTrimming="CharacterEllipsis"> 
         <ContentPresenter></ContentPresenter> 
          </TextBlock> 
         </Grid> 

        </Grid> 
        <ControlTemplate.Triggers> 
         <Trigger Property="IsChecked" Value="True"> 
          <Setter Property="Opacity" Value="1" TargetName="Check"></Setter> 
         </Trigger> 
         <Trigger Property="IsChecked" Value="False"> 
          <Setter Property="Opacity" Value="0" TargetName="Check"></Setter> 
         </Trigger> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
     <Setter Property="FocusVisualStyle"> 
      <Setter.Value> 
       <Style TargetType="Control"> 
        <Setter Property="Template"> 
         <Setter.Value> 
          <ControlTemplate> 
           <Border BorderBrush="{DynamicResource customBlueBrush}" SnapsToDevicePixels="True" BorderThickness="1" Margin="-5,1,3,1" /> 
          </ControlTemplate> 
         </Setter.Value> 
        </Setter> 
       </Style> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</Window.Resources> 

<Grid x:Name="gd" > 
    <Expander Width="500"> 
     <Expander.Header> 
      <ListBox Background="Transparent" IsHitTestVisible="False" BorderBrush="Transparent" ScrollViewer.HorizontalScrollBarVisibility="Hidden" ScrollViewer.VerticalScrollBarVisibility="Disabled" BorderThickness="0" ItemsSource="{Binding ElementName=lst,Path=SelectedItems}"> 
       <ListBox.ItemsPanel> 
        <ItemsPanelTemplate> 
         <WrapPanel Orientation="Horizontal"></WrapPanel> 
        </ItemsPanelTemplate> 
       </ListBox.ItemsPanel> 
       <ListBox.ItemTemplate> 
        <DataTemplate> 
         <TextBlock Text="{Binding ContentData}"/> 
        </DataTemplate> 
       </ListBox.ItemTemplate> 
      </ListBox> 
     </Expander.Header> 
     <Expander.Content> 
      <ListBox Background="Transparent" ItemContainerStyle="{StaticResource itemstyle}" HorizontalContentAlignment="Stretch" x:Name="lst" SelectionMode="Multiple"> 
       <ListBox.ItemTemplate> 
        <DataTemplate> 
         <CheckBox x:Name="checkBox" IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}, Path=IsSelected}" Content="{Binding ContentData}"></CheckBox> 
        </DataTemplate> 
       </ListBox.ItemTemplate> 
      </ListBox> 
     </Expander.Content> 
    </Expander> 
</Grid> 

C# код

public partial class Window1 : Window 
{ 
    public Window1() 
    { 
     InitializeComponent();   
     ObservableCollection<Customer> custdata = new ObservableCollection<Customer>(); 
     custdata.Add(new Customer() { ContentData = "content1" }); 
     custdata.Add(new Customer() { ContentData = "content2" }); 
     custdata.Add(new Customer() { ContentData = "content3" }); 
     custdata.Add(new Customer() { ContentData = "content4" }); 
     custdata.Add(new Customer() { ContentData = "content5" }); 
     custdata.Add(new Customer() { ContentData = "content6" }); 
     lst.ItemsSource = custdata; 
    } 
} 
public class Customer 
{ 
    public string ContentData { get; set; } 
} 

Результат

enter image description here

+0

Не позволяет ли расширитель увеличить свой собственный размер при открытии, вместо того, чтобы всплывать, не затрагивая макет? – tomosius

2

Konrad,

Я также решил использовать ComboBox таким образом, потому что код был просто мертв просто. Самый простой способ найти всплывающее окно ComboBox - подключиться к событию PreviewMouseDown элемента управления в шаблоне элементов ComboBox. самостоятельно обработайте поведение, а затем отметьте обработанное событие мыши. Отлично работает для меня. В приведенном ниже примере каждый объект в FilterItems представляет собой простую модель вида с свойством Text и свойством IsChecked.

<ComboBox IsEditable="True" IsReadOnly="False" ItemsSource="{Binding FilterItems}"> 
    <ComboBox.ItemTemplate> 
     <DataTemplate> 
      <CheckBox IsChecked="{Binding IsChecked}" Content="{Binding Text}" 
         PreviewMouseDown="FilterComboBox_PreviewMouseDown"/> 
     </DataTemplate> 
    </ComboBox.ItemTemplate> 
</ComboBox> 

И тогда мой обработчик событий:

private void FilterComboBox_PreviewMouseDown(object sender, MouseButtonEventArgs e) 
{ 
    var cb = sender as CheckBox; 
    if (cb != null) 
    { 
     cb.IsChecked = !cb.IsChecked; 
     e.Handled = true; 
    } 
} 
Смежные вопросы