问题描述
我有一个组合框,里面有一堆复选框.我希望用户能够在组合框关闭(或由用户自己关闭)之前多次单击.现在的问题是每次点击一个复选框时,组合框都会关闭,迫使想要选择多个选项的用户重新打开它几次.
I've got a combobox and it's populated with a bunch of checkboxes. I wish the user to be able to click multiple times before the combobox closes (or is closed by the user themselves). The problems right now is that each time a checkbox is clicked, the combobox closes, forcing the user who wants to select multiple options to re-open it several times.
我发现了关于同一主题的其他问题,但这些问题适用于 Silverlight、Qt 等.比较标签.
I've found other questions on the same subject but those apply to Silverlight, Qt etc. comparing the tags.
我试过设置 StayOpenOnEdit 但这并没有奏效.据我所知,没有任何财产可以解决我的问题.这让人怀疑我可能把错误的组件放在一起.
I've tried setting StayOpenOnEdit but that didn't do the trick. As far I could see, there's no property addressing my issue. That creates a suspicion that I might be barning up the wrong component all together.
- 如何防止组合框在单击其中的复选框后自动关闭?
- 是否有更适合此类任务的组件?如果有,它的名称是什么?
请注意,即使#2 的答案是是",出于纯粹的学术原因,我仍然对#1 感到好奇.
Please note that even if the answer to #2 is "yes", I'm still curious of #1 for purely academic reasons.
我玩过切换按钮和列表框,正如有人在帖子中建议的那样.但是,这只会导致始终完全显示的所有复选框列表背后有一些灰色的东西(我假设它是切换器).也许我在标记中做了一些不太聪明的事情.
I've played with toggle button and list box, as someone suggested in a post. However, the that led only to an always fully shown list of all the checkboxes with some greyish thing behind it (which I'm assuming is the toggler). Perhaps I did something less clever in the mark-up.
<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>
关键是要实现这样的事情但它需要是一个标准的 WPF 控件(所有选定项目的连接线很好,但不是必须的).另外,我读过一些关于绑定和处理尚未完全开发的投诉,我觉得有点可疑.
The point is to achieve something like this but it needs to be a standard WPF control (the concatenated line of all selected items is nice but not a must). Also, I've read the complaints that the binding and handling is not fully developed yet and I feel a bit suspicious.
推荐答案
使用扩展器控件可以实现多项目选择,单选后不关闭弹窗.
Using Exapander Control you can achieve multple item selection without closing popup after single selection.
为了理解,请单独运行此代码.
For understanding please run this code separately.
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; }
}
结果
这篇关于CheckComboBox:单击选择后如何防止组合框关闭?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!