禁止/阻止选择 wpf 中禁用的组合框项目

Posted

技术标签:

【中文标题】禁止/阻止选择 wpf 中禁用的组合框项目【英文标题】:Disallow/Block selection of disabled combobox item in wpf 【发布时间】:2014-01-20 07:33:39 【问题描述】:

我正在编写一个应用程序,其中我想禁用 ComboBox 中的几个项目,并且还想禁止/阻止选择禁用的项目。请注意,主窗口中的 ComboBox 有另一个 ComboBox 作为 ComboBox Item init(由数据模板选择器在运行时决定)。

使用下面的代码,我可以禁用 ComboBox 中的 ComboBox,但它不会阻止用户选择该禁用的 ComboBox 项。禁止/阻止选择禁用项目的任何帮助都会有所帮助。

下面是代码sn-ps

主窗口中的组合框:

<Grid>
    <ComboBox HorizontalAlignment="Left" VerticalAlignment="Top" 
              Width="120" Margin="87.2,44.8,0,0" 
              ItemsSource="Binding Cars" 
              ItemsPanel="DynamicResource ItemsPanelTemplateHorizontal"
              ItemTemplateSelector="StaticResource QualityComboBoxTemplateSelector"
              SelectedItem="Binding SelectedItm"/>
</Grid>

数据模板选择器:

public class QualityComboBoxTemplateSelector : DataTemplateSelector

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    
        var element = container as FrameworkElement;

        var dataTemplate = element.FindResource(((item is string) && item.Equals("Ferrari")) ?
                                                       "DataTemplateTopLevelCombobox2" : "DataTemplateTopLevelCombobox1") as DataTemplate;

        return dataTemplate;
    

以上 ComboBox 的数据模板:

<DataTemplate x:Key="DataTemplateTopLevelCombobox1">
    <Border BorderBrush="Black" BorderThickness="1" >
        <TextBlock HorizontalAlignment="Left" 
                   TextWrapping="Wrap" Text="Binding"     
                   VerticalAlignment="Top"/>
    </Border>
</DataTemplate>

<DataTemplate x:Key="DataTemplateTopLevelCombobox2">
    <Border Width="100">
        <ComboBox Text="Custom" Height="21.96"
        ItemsSource="Binding DataContext.Models, RelativeSource=RelativeSource FindAncestor, AncestorType=x:Type Window"
        IsEnabled="Binding DataContext.EnableCombo, RelativeSource=RelativeSource FindAncestor, AncestorType=x:Type Window" />
    </Border>
</DataTemplate>

【问题讨论】:

【参考方案1】:

您可以通过将ComboBoxItemIsEnabled 属性设置为false 来实现此目的;

因此,ComboBox 的ItemSource 中的每个项目(即在您的情况下为Cars)都可以是具有某些属性(例如IsSelectable)的对象,该属性指定是否应启用或禁用它,然后将其与样式一起使用不可选择的项目。像这样 -

<Style TargetType="ComboBoxItem"> 
   <Setter Property="IsEnabled" Value="Binding IsSelectable"/> 
</Style> 

更新:

<Grid>
    <ComboBox
        Width="120"
        Margin="87.2,44.8,0,0"
        HorizontalAlignment="Left"
        VerticalAlignment="Top"
        ItemTemplateSelector="StaticResource QualityComboBoxTemplateSelector"
        ItemsPanel="DynamicResource ItemsPanelTemplateHorizontal"
        ItemsSource="Binding Cars"
        SelectedItem="Binding SelectedItm">
        <ComboBox.ItemContainerStyle>
            <Style TargetType="ComboBoxItem">
                <Setter
                    Property="IsEnabled"
                    Value="Binding IsSelectable" />
            </Style>
        </ComboBox.ItemContainerStyle>
    </ComboBox>
</Grid>

【讨论】:

其实我没有用ComboboxItemStyle,我用的是DataTemplate。 @vmore 我已经更新了我的答案,展示了如何应用 ComboBoxItem 样式。 @vmore 很高兴它有帮助:) 这不是防止选择的一致方式。您仍然可以通过将焦点放在控件中并键入来搜索它来选择禁用的项目。它会毫无问题地选择它。 我希望我这样做了,现在我正在通过允许选择但阻止任何进一步的操作(即选择被认为对表单无效)来解决它。您必须挂钩查找行为以过滤掉所有禁用的项目。不过,这似乎是控件的一个明显错误,所以我不确定为什么它仍然会以这种方式运行。【参考方案2】:

解决@JordyBoom 指出的问题。

ItemsContainerGenerator 在下拉菜单至少打开一次之前不会生成项目。

因此,如果您在窗口的加载事件处理程序中打开下拉菜单并再次将其关闭,那么所有的鼠标和键盘选择都应该可以正常工作。

    public MainWindow()
    
        InitializeComponent();
        this.Loaded += new RoutedEventHandler(onLoaded);
    

    private void onLoaded(object sender, RoutedEventArgs e)
    
         cmbx.IsDropDownOpen = true;
         cmbx.IsDropDownOpen = false;
    

来源:WPF: Making combo box items disabled – also when accessed using the keyboard

【讨论】:

谢谢。上下箭头键可用于在组合被删除之前浏览项目,并且允许在没有此修复的情况下进行选择。禁用的项目是某些人的分隔符。

以上是关于禁止/阻止选择 wpf 中禁用的组合框项目的主要内容,如果未能解决你的问题,请参考以下文章

WPF 组合框禁用背景颜色

启用/禁用 Excel 2007 组合框

在 WPF / C# 中选择绑定项目后维护组合框文本

wpf的组合框中显示新的选定项后如何显示对话框?

使用工具提示 WPF 在数据网格中填充组合框

选择组合框时设置文本框的属性 WPF XAML