Disallow/Block selection of disabled combobox item in wpf

33,640

Solution 1

You can achieve this by setting IsEnabled property of a ComboBoxItem to false;

So each item in ComboBox's ItemSource (i.e. Cars in your case) can be an object having some property (say IsSelectable) specifying whether it should be enabled or disabled and then use it with a style to make an item un-selectable. something like this -

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

Update:

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

Solution 2

To solve the problem pointed by @JordyBoom.

ItemsContainerGenerator does not generate items until dropdown is opened at least once.

So if you open the drop down and close it again in window’s loaded event handler then all supposed to work fine with mouse as well as with keyboard selection.

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

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

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

Share:
33,640

Related videos on Youtube

vmore
Author by

vmore

Software engineer !

Updated on January 19, 2020

Comments

  • vmore
    vmore over 4 years

    I'm writing an application wherein I would like to disable few items in the ComboBox and also want to disallow/block selection of disabled items. Please note ComboBox in main window has another ComboBox as ComboBox Item init (that is decided at run time by data template selector).

    With below code I'm able to disable a ComboBox within ComboBox but it would not stop user from selecting that disabled ComboBox item. Any help in disallow/block selection of disabled items would be helpful.

    Below are the code snippets

    ComboBox in main window:

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

    Data template selector:

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

    Data templates for above 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>
    
  • vmore
    vmore over 10 years
    Actually I'm not using ComboboxItemStyle, I'm using DataTemplate.
  • akjoshi
    akjoshi over 10 years
    @vmore I have updated my answer showing how you can apply ComboBoxItem style.
  • akjoshi
    akjoshi over 10 years
    @vmore Glad it helped :)
  • Jordy Boom
    Jordy Boom almost 10 years
    This isn't a consistent way of preventing selection. You can still select disabled items by putting focus in the control and typing to search for it. It will select it without a problem.
  • akjoshi
    akjoshi over 9 years
    @JordyBoom Thanks Jordy, I haven't tried this scenario but sounds weird. Let everyone know if you have any workaround to resolve this or any links.
  • Jordy Boom
    Jordy Boom over 9 years
    I wish I did, for now I'm working around it by allowing selection but by preventing any further action (i.e. the selection is considered invalid for the form). You'd have to hook into the look-up behavior to filter out all disabled items. Seems like an obvious bug for the control though, so I'm not sure why it still behaves this way.
  • James_UK_DEV
    James_UK_DEV almost 8 years
    Thanks. The up and down arrow keys can be used to go through the items before the combo is dropped, and will allow selection without this fix. The disabled item is a separator for some people.
  • TheHitchenator
    TheHitchenator about 2 years
    If the selected item is bound to some property, you can essentially make it impossible to select by having the setter for the property check the value before changing it - bit hacky and not a fun workaround for anyone looking at your code later but as long as you properly comment it, should be okay