Search code examples
c#wpfxamlcomboboxcontroltemplate

Disable either the Togglebutton or Popup Dropdown of a Combobox via property binding


I want to be able to disable the combobox dropdown for the user by a property binding in a ViewModel. The user should only in certain situations be able to use the dropdown. But it should always be possible to see and edit the SelectedItem.

There are some similar questions here in Stackoverflow, but none gets me to the solution for this problem. So far i placed a combobox via the Toolbox in a window and the started editing a copy of the whole comboxbox tempalte by selecting the option Editing a copy of the template

1. Tried directy to edit the ToggleButton Style - hides the whole combobox
<Setter Property="Template">
  <Setter.Value>
    <ControlTemplate TargetType="{x:Type ToggleButton}">
      <ControlTemplate.Triggers>
        <DataTrigger Binding="{Binding IsCombboxEnabled}" Value="True">
          <Setter Property="Visibility" Value="Visible" />
        </DataTrigger>
        <DataTrigger Binding="{Binding IsCombboxEnabled}" Value="False">
          <Setter Property="Visibility" Value="Hidden" />
        </DataTrigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>
   </Setter.Value>
 </Setter>
  • this hides the whole combobox
  • setting IsEnabled, disables the whole combobox, but i want to be able to use f.e. the textblock's editing property while the dropdown is disabled
  • IsChecked Property Trigger in the style does not change anything

2. Setting IsChecked directy in the ToggleButton works

This is properbly closer to the solution: Editing IsChecked directly within the ToggleButton Usage:

            <ToggleButton x:Name="toggleButton" 
                          Background="{TemplateBinding Background}" 
                          BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" 
                          Grid.ColumnSpan="2" 
                          IsChecked="{Binding IsCombboxEnabled}" 
                          Style="{StaticResource ComboBoxToggleButton}"/>

This gets me halfway there, i gues. It is now not possible to open the PopUp at all. I am struggeling now to set up kind of a MultiDataTrigger binding on properties and data to combine IsChecked="{Binding IsCombboxEnabled}" and the replaced line IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource Mode=TemplatedParent}}"

How do i combine the two statements correctly? Or is there a more clean, elegant way to achieve this?

Xaml Code (Custom ComboboxEditTemplate is left out)
<Window x:Class="WpfApp1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WpfApp1"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800"
xmlns:theme="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero2">
<Window.Resources>
    <Style x:Key="FocusVisual">
        <Setter Property="Control.Template">
            <Setter.Value>
                <ControlTemplate>
                    <Rectangle Margin="2" StrokeDashArray="1 2" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" SnapsToDevicePixels="true" StrokeThickness="1"/>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <LinearGradientBrush x:Key="ComboBox.Static.Background" EndPoint="0,1" StartPoint="0,0">
        <GradientStop Color="#FFF0F0F0" Offset="0.0"/>
        <GradientStop Color="#FFE5E5E5" Offset="1.0"/>
    </LinearGradientBrush>
    <SolidColorBrush x:Key="ComboBox.Static.Border" Color="#FFACACAC"/>
    <SolidColorBrush x:Key="ComboBox.Static.Glyph" Color="#FF606060"/>
    <SolidColorBrush x:Key="ComboBox.Static.Editable.Background" Color="#FFFFFFFF"/>
    <SolidColorBrush x:Key="ComboBox.Static.Editable.Border" Color="#FFABADB3"/>
    <SolidColorBrush x:Key="ComboBox.Static.Editable.Button.Background" Color="Transparent"/>
    <SolidColorBrush x:Key="ComboBox.Static.Editable.Button.Border" Color="Transparent"/>
    <LinearGradientBrush x:Key="ComboBox.MouseOver.Background" EndPoint="0,1" StartPoint="0,0">
        <GradientStop Color="#FFECF4FC" Offset="0.0"/>
        <GradientStop Color="#FFDCECFC" Offset="1.0"/>
    </LinearGradientBrush>
    <SolidColorBrush x:Key="ComboBox.MouseOver.Border" Color="#FF7EB4EA"/>
    <SolidColorBrush x:Key="ComboBox.MouseOver.Glyph" Color="#FF000000"/>
    <SolidColorBrush x:Key="ComboBox.MouseOver.Editable.Background" Color="#FFFFFFFF"/>
    <SolidColorBrush x:Key="ComboBox.MouseOver.Editable.Border" Color="#FF7EB4EA"/>
    <LinearGradientBrush x:Key="ComboBox.MouseOver.Editable.Button.Background" EndPoint="0,1" StartPoint="0,0">
        <GradientStop Color="#FFEBF4FC" Offset="0.0"/>
        <GradientStop Color="#FFDCECFC" Offset="1.0"/>
    </LinearGradientBrush>
    <SolidColorBrush x:Key="ComboBox.MouseOver.Editable.Button.Border" Color="#FF7EB4EA"/>
    <LinearGradientBrush x:Key="ComboBox.Pressed.Background" EndPoint="0,1" StartPoint="0,0">
        <GradientStop Color="#FFDAECFC" Offset="0.0"/>
        <GradientStop Color="#FFC4E0FC" Offset="1.0"/>
    </LinearGradientBrush>
    <SolidColorBrush x:Key="ComboBox.Pressed.Border" Color="#FF569DE5"/>
    <SolidColorBrush x:Key="ComboBox.Pressed.Glyph" Color="#FF000000"/>
    <SolidColorBrush x:Key="ComboBox.Pressed.Editable.Background" Color="#FFFFFFFF"/>
    <SolidColorBrush x:Key="ComboBox.Pressed.Editable.Border" Color="#FF569DE5"/>
    <LinearGradientBrush x:Key="ComboBox.Pressed.Editable.Button.Background" EndPoint="0,1" StartPoint="0,0">
        <GradientStop Color="#FFDAEBFC" Offset="0.0"/>
        <GradientStop Color="#FFC4E0FC" Offset="1.0"/>
    </LinearGradientBrush>
    <SolidColorBrush x:Key="ComboBox.Pressed.Editable.Button.Border" Color="#FF569DE5"/>
    <SolidColorBrush x:Key="ComboBox.Disabled.Background" Color="#FFF0F0F0"/>
    <SolidColorBrush x:Key="ComboBox.Disabled.Border" Color="#FFD9D9D9"/>
    <SolidColorBrush x:Key="ComboBox.Disabled.Glyph" Color="#FFBFBFBF"/>
    <SolidColorBrush x:Key="ComboBox.Disabled.Editable.Background" Color="#FFFFFFFF"/>
    <SolidColorBrush x:Key="ComboBox.Disabled.Editable.Border" Color="#FFBFBFBF"/>
    <SolidColorBrush x:Key="ComboBox.Disabled.Editable.Button.Background" Color="Transparent"/>
    <SolidColorBrush x:Key="ComboBox.Disabled.Editable.Button.Border" Color="Transparent"/>
    <Style x:Key="ComboBoxToggleButton" TargetType="{x:Type ToggleButton}">
        <Setter Property="OverridesDefaultStyle" Value="true"/>
        <Setter Property="IsTabStop" Value="false"/>
        <Setter Property="Focusable" Value="false"/>
        <Setter Property="ClickMode" Value="Press"/>
        <Setter Property="IsChecked" Value="{Binding IsToggleButtonEnabled}"></Setter>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ToggleButton}">
                    <Border x:Name="templateRoot" 
                            Background="{StaticResource ComboBox.Static.Background}" 
                            BorderBrush="{StaticResource ComboBox.Static.Border}" 
                            BorderThickness="{TemplateBinding BorderThickness}"
                            SnapsToDevicePixels="true">
                        <Border x:Name="splitBorder" BorderBrush="Transparent" 
                                BorderThickness="1"
                                HorizontalAlignment="Right" 
                                Margin="0" 
                                SnapsToDevicePixels="true" 
                                Width="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}">
                            <Path x:Name="arrow" Data="F1 M 0,0 L 2.667,2.66665 L 5.3334,0 L 5.3334,-1.78168 L 2.6667,0.88501 L0,-1.78168 L0,0 Z" Fill="{StaticResource ComboBox.Static.Glyph}" HorizontalAlignment="Center" Margin="0" VerticalAlignment="Center"/>
                        </Border>
                    </Border>
                    <ControlTemplate.Triggers>
                        <MultiDataTrigger>
                            <MultiDataTrigger.Conditions>
                                <Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="true"/>
                                <Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Mode=Self}}" Value="false"/>
                                <Condition Binding="{Binding IsPressed, RelativeSource={RelativeSource Mode=Self}}" Value="false"/>
                                <Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Mode=Self}}" Value="true"/>
                            </MultiDataTrigger.Conditions>
                            <Setter Property="Background" TargetName="templateRoot" Value="{StaticResource ComboBox.Static.Editable.Background}"/>
                            <Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource ComboBox.Static.Editable.Border}"/>
                            <Setter Property="Background" TargetName="splitBorder" Value="{StaticResource ComboBox.Static.Editable.Button.Background}"/>
                            <Setter Property="BorderBrush" TargetName="splitBorder" Value="{StaticResource ComboBox.Static.Editable.Button.Border}"/>
                        </MultiDataTrigger>
                        <Trigger Property="IsMouseOver" Value="true">
                            <Setter Property="Fill" TargetName="arrow" Value="{StaticResource ComboBox.MouseOver.Glyph}"/>
                        </Trigger>
                        <!--<DataTrigger Binding="{Binding IsToggleButtonEnabled}" Value="True">
                            <Setter Property="IsEnabled" Value="True" />
                        </DataTrigger>
                        <DataTrigger Binding="{Binding IsToggleButtonEnabled}" Value="False">
                            <Setter Property="IsEnabled" Value="False" />
                        </DataTrigger>-->
                        <DataTrigger Binding="{Binding IsToggleButtonEnabled}" Value="True">
                            <Setter Property="IsChecked" Value="True" />
                        </DataTrigger>
                        <DataTrigger Binding="{Binding IsToggleButtonEnabled}" Value="False">
                            <Setter Property="IsChecked" Value="False" />
                        </DataTrigger>
                        <MultiDataTrigger>
                            <MultiDataTrigger.Conditions>
                                <Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Mode=Self}}" Value="true"/>
                                <Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="false"/>
                            </MultiDataTrigger.Conditions>
                            <Setter Property="Background" TargetName="templateRoot" Value="{StaticResource ComboBox.MouseOver.Background}"/>
                            <Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource ComboBox.MouseOver.Border}"/>
                        </MultiDataTrigger>
                        
                        <!--<MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="IsChecked" Value="True" />
                                <Condition Property="{Binding RelativeSource={RelativeSource Mode=Self},Path=IsToggleButtonEnabled}" Value="True" />
                            </MultiTrigger.Conditions>
                            <MultiTrigger.Setters>
                                <Setter Property="IsChecked" Value="True" />
                            </MultiTrigger.Setters>
                        </MultiTrigger>-->


                        <MultiDataTrigger>
                            <MultiDataTrigger.Conditions>
                                <Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Mode=Self}}" Value="true"/>
                                <Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="true"/>
                            </MultiDataTrigger.Conditions>
                            <Setter Property="Background" TargetName="templateRoot" Value="{StaticResource ComboBox.MouseOver.Editable.Background}"/>
                            <Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource ComboBox.MouseOver.Editable.Border}"/>
                            <Setter Property="Background" TargetName="splitBorder" Value="{StaticResource ComboBox.MouseOver.Editable.Button.Background}"/>
                            <Setter Property="BorderBrush" TargetName="splitBorder" Value="{StaticResource ComboBox.MouseOver.Editable.Button.Border}"/>
                        </MultiDataTrigger>
                        <Trigger Property="IsPressed" Value="true">
                            <Setter Property="Fill" TargetName="arrow" Value="{StaticResource ComboBox.Pressed.Glyph}"/>
                        </Trigger>
                        <MultiDataTrigger>
                            <MultiDataTrigger.Conditions>
                                <Condition Binding="{Binding IsPressed, RelativeSource={RelativeSource Mode=Self}}" Value="true"/>
                                <Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="false"/>
                            </MultiDataTrigger.Conditions>
                            <Setter Property="Background" TargetName="templateRoot" Value="{StaticResource ComboBox.Pressed.Background}"/>
                            <Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource ComboBox.Pressed.Border}"/>
                        </MultiDataTrigger>
                        <MultiDataTrigger>
                            <MultiDataTrigger.Conditions>
                                <Condition Binding="{Binding IsPressed, RelativeSource={RelativeSource Mode=Self}}" Value="true"/>
                                <Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="true"/>
                            </MultiDataTrigger.Conditions>
                            <Setter Property="Background" TargetName="templateRoot" Value="{StaticResource ComboBox.Pressed.Editable.Background}"/>
                            <Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource ComboBox.Pressed.Editable.Border}"/>
                            <Setter Property="Background" TargetName="splitBorder" Value="{StaticResource ComboBox.Pressed.Editable.Button.Background}"/>
                            <Setter Property="BorderBrush" TargetName="splitBorder" Value="{StaticResource ComboBox.Pressed.Editable.Button.Border}"/>
                        </MultiDataTrigger>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Fill" TargetName="arrow" Value="{StaticResource ComboBox.Disabled.Glyph}"/>
                        </Trigger>
                        <MultiDataTrigger>
                            <MultiDataTrigger.Conditions>
                                <Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Mode=Self}}" Value="false"/>
                                <Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="false"/>
                            </MultiDataTrigger.Conditions>
                            <Setter Property="Background" TargetName="templateRoot" Value="{StaticResource ComboBox.Disabled.Background}"/>
                            <Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource ComboBox.Disabled.Border}"/>
                        </MultiDataTrigger>
                        <MultiDataTrigger>
                            <MultiDataTrigger.Conditions>
                                <Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Mode=Self}}" Value="false"/>
                                <Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="true"/>
                            </MultiDataTrigger.Conditions>
                            <Setter Property="Background" TargetName="templateRoot" Value="{StaticResource ComboBox.Disabled.Editable.Background}"/>
                            <Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource ComboBox.Disabled.Editable.Border}"/>
                            <Setter Property="Background" TargetName="splitBorder" Value="{StaticResource ComboBox.Disabled.Editable.Button.Background}"/>
                            <Setter Property="BorderBrush" TargetName="splitBorder" Value="{StaticResource ComboBox.Disabled.Editable.Button.Border}"/>
                        </MultiDataTrigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <ControlTemplate x:Key="ComboBoxTemplate" TargetType="{x:Type ComboBox}">
        <Grid x:Name="templateRoot" SnapsToDevicePixels="true">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition MinWidth="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" Width="0"/>
            </Grid.ColumnDefinitions>
            <Popup x:Name="PART_Popup" AllowsTransparency="true" Grid.ColumnSpan="2" IsOpen="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource Mode=TemplatedParent}}" Margin="1" Placement="Bottom" PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}">
                <theme:SystemDropShadowChrome x:Name="shadow" Color="Transparent" MinWidth="{Binding ActualWidth, ElementName=templateRoot}" MaxHeight="{TemplateBinding MaxDropDownHeight}">
                    <Border x:Name="dropDownBorder" Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}" BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}" BorderThickness="1">
                        <ScrollViewer x:Name="DropDownScrollViewer">
                            <Grid x:Name="grid" RenderOptions.ClearTypeHint="Enabled">
                                <Canvas x:Name="canvas" HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
                                    <Rectangle x:Name="opaqueRect" Fill="{Binding Background, ElementName=dropDownBorder}" Height="{Binding ActualHeight, ElementName=dropDownBorder}" Width="{Binding ActualWidth, ElementName=dropDownBorder}"/>
                                </Canvas>
                                <ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Contained" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                            </Grid>
                        </ScrollViewer>
                    </Border>
                </theme:SystemDropShadowChrome>
            </Popup>
            <ToggleButton x:Name="toggleButton" 
                          Background="{TemplateBinding Background}" 
                          BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" 
                          Grid.ColumnSpan="2" 
                          IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource Mode=TemplatedParent}}" 
                          Style="{StaticResource ComboBoxToggleButton}"/>
            <ContentPresenter x:Name="contentPresenter" ContentStringFormat="{TemplateBinding SelectionBoxItemStringFormat}" 
                              ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" 
                              Content="{TemplateBinding SelectionBoxItem}" 
                              ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" 
                              HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                              IsHitTestVisible="false" Margin="{TemplateBinding Padding}" 
                              SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" 
                              VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
        </Grid>
        <ControlTemplate.Triggers>
            
               
            
            <Trigger Property="HasDropShadow" SourceName="PART_Popup" Value="true">
                <Setter Property="Margin" TargetName="shadow" Value="0,0,5,5"/>
                <Setter Property="Color" TargetName="shadow" Value="#71000000"/>
            </Trigger>
            <Trigger Property="HasItems" Value="false">
                <Setter Property="Height" TargetName="dropDownBorder" 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 Property="ScrollViewer.CanContentScroll" SourceName="DropDownScrollViewer" Value="false">
                <Setter Property="Canvas.Top" TargetName="opaqueRect" 
                        Value="{Binding VerticalOffset, ElementName=DropDownScrollViewer}"/>
                <Setter Property="Canvas.Left" TargetName="opaqueRect" 
                        Value="{Binding HorizontalOffset, ElementName=DropDownScrollViewer}"/>
            </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>
    <Style x:Key="CmbboxToggleButtonTemplate" TargetType="{x:Type ComboBox}">
        <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
        <Setter Property="Background" Value="{StaticResource ComboBox.Static.Background}"/>
        <Setter Property="BorderBrush" Value="{StaticResource ComboBox.Static.Border}"/>
        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
        <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
        <Setter Property="Padding" Value="6,3,5,3"/>
        <Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
        <Setter Property="ScrollViewer.PanningMode" Value="Both"/>
        <Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
        <Setter Property="Template" Value="{StaticResource ComboBoxTemplate}"/>

    </Style>
</Window.Resources>
<Window.DataContext>
    <local:ViewModel></local:ViewModel>
</Window.DataContext>

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"></ColumnDefinition>
        <ColumnDefinition Width="*"></ColumnDefinition>
        <ColumnDefinition Width="*"></ColumnDefinition>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"></RowDefinition>
        <RowDefinition Height="*"></RowDefinition>
        <RowDefinition Height="*"></RowDefinition>
    </Grid.RowDefinitions>
    <ComboBox Style="{DynamicResource CmbboxToggleButtonTemplate}" 
              ItemsSource="{Binding Items}"
              SelectedItem="{Binding SelectedItem}"
              Grid.Column="1"  Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center" Width="200">
    </ComboBox>
    <Button Content="On/Off" Margin="50" Command="{Binding SwitchCommand}"></Button>
    <TextBlock Grid.Row="1 " Grid.Column="0" Text="{Binding State}"></TextBlock>
</Grid>
</Window>
ViewModel (INotifyPropertyChanged implementation left out)
public class ViewModel : INotifyPropertyChanged
{
private string state;
private List<string> items;
private string selectedItem;
private bool isToggleButtonEnabled;
private Visibility visibilityCombobox;
public ViewModel()
{
    Items = new List<string> { "item1", "item2", "item3" };
    State = "On";
}

public List<string> Items
{
    get => items;
    set
    {
        items = value;
        OnPropertyChanged();
    }
}

public ICommand SwitchCommand => new RelayCommand(() =>
{
    VisibilityCombobox = visibilityCombobox == Visibility.Collapsed ?  Visibility.Visible : Visibility.Collapsed;
});

public bool IsToggleButtonEnabled
{
    get => isToggleButtonEnabled;
    set
    {
        isToggleButtonEnabled = value;
        OnPropertyChanged();
    }
}

public Visibility VisibilityCombobox
{
    get => visibilityCombobox;
    set
    {
        visibilityCombobox = value;
        State = value == Visibility.Visible ? "On" : "Off";
        OnPropertyChanged();
    }
}

public string SelectedItem
{
    get => selectedItem;
    set
    {
        selectedItem = value;
        OnPropertyChanged();
    }
}

public string State
{
    get => state;
    set
    {
        state = value;
        OnPropertyChanged();
    }}}

Update

The preconditions are:

  • The user should always be able to edit the SelectedItem (IsEditable="True")
  • i want to be able - depending on a property in a ViewModel - to not let the user expand/use the Dropdown menu

I am struggeling to control the Dropdown Menu via a property binding.


Solution

  • I think that you can greatly simplify your approach and still achieve what I think you are you are looking for.

    If your goal is to make the ComboBox look like and act like a TextBlo when it is disabled, you could simply swap out the control depending on the state.

    public bool IsToggleButtonEnabled
    {
        get => isToggleButtonEnabled;
        set
        {
            isToggleButtonEnabled = value;
            OnPropertyChanged();
            // also notify that the dependent properties changed
            OnPropertyChanged(nameof(ComboBoxVisibility));
            OnPropertyChanged(nameof(TextBlockVisibility));
        }
    }
    public Visibility ComboBoxVisibility => IsToggleButtonEnabled ? Visibility.Visible : Visibility.Collapsed;
    public Visibility TextBlockVisibility => IsToggleButtonEnabled ? Visibility.Hidden : Visibility.Visible;
    
    <ToggleButton IsChecked="{Binding IsToggleButtonEnabled}"
                    Content="{Binding State}"
                    Grid.Row="2"
                    Margin="2,0"/>
    <ComboBox Grid.Column="1"
                Grid.Row="2"
                Margin="2,0"
                ItemsSource="{Binding Items}"
                SelectedItem="{Binding SelectedItem}"
                IsEnabled="{Binding IsToggleButtonEnabled}"
                IsEditable="True"
                Text="{Binding SelectedItem, UpdateSourceTrigger=PropertyChanged}"
                Visibility="{Binding ComboBoxVisibility}"/>
    <TextBox Grid.Column="1"
                Grid.Row="2"
                Padding="2"
                Margin="2,0"
                Text="{Binding SelectedItem, UpdateSourceTrigger=PropertyChanged}"
                Visibility="{Binding TextBlockVisibility}"/>
    

    Result:

    result

    You can see the full code to produce those two gifs here: