5

I want to make impossible checking checkbox in WPF (from C# code). Only unchecking would be allowed.
How can I do it?

PS.
Writing event handler on Click event which would immediately uncheck checkbox after checking it is not acceptable.

[edit]
Checkbox should always be enabled, so that user can think that checkbox can be checked. It's strange but it's specific programme.

patryk.beza
  • 4,876
  • 5
  • 37
  • 56
  • 2
    If the user un-checks the box will they be able to check it again? – Dylan Jun 13 '12 at 19:21
  • Does this answer your question? [A read-only CheckBox in C# WPF](https://stackoverflow.com/questions/921921/a-read-only-checkbox-in-c-sharp-wpf) – Mike Nakis Aug 04 '20 at 11:01

4 Answers4

10
<CheckBox Content="Checkbox"
          IsEnabled="{Binding RelativeSource={RelativeSource Self}, Path=IsChecked}" />

Edit after being informed that the checkbox always has to look to be in an checkable state, even when it's not. Here is a working example:

<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero" x:Class="WpfTest.MainWindow"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <ControlTemplate x:Key="DeceptiveCheckbox" TargetType="{x:Type CheckBox}">
            <BulletDecorator Background="Transparent" SnapsToDevicePixels="True">
                <BulletDecorator.Bullet>
                    <Microsoft_Windows_Themes:BulletChrome BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" IsChecked="{TemplateBinding IsChecked}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}"/>
                </BulletDecorator.Bullet>
                <ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
            </BulletDecorator>
            <ControlTemplate.Triggers>
                <Trigger Property="HasContent" Value="True">
                    <Setter Property="FocusVisualStyle">
                        <Setter.Value>
                            <Style>
                                <Setter Property="Control.Template">
                                    <Setter.Value>
                                        <ControlTemplate>
                                            <Rectangle Margin="14,0,0,0" SnapsToDevicePixels="True" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
                                        </ControlTemplate>
                                    </Setter.Value>
                                </Setter>
                            </Style>
                        </Setter.Value>
                    </Setter>
                    <Setter Property="Padding" Value="4,0,0,0"/>
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
    </Window.Resources>
    <Grid>
        <CheckBox Content="CheckBox"  IsEnabled="{Binding IsChecked, RelativeSource={RelativeSource Self}}" Template="{StaticResource DeceptiveCheckbox}" />
    </Grid>
</Window>

The fix was simple. I simply created a copy of the current checkbox template and removed:

<Trigger Property="IsEnabled" Value="False">
    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
Nick Babcock
  • 6,111
  • 3
  • 27
  • 43
3

How about this:

<Grid>
    <Grid.Resources>
        <Style TargetType="CheckBox">
            <Style.Triggers>
                <Trigger Property="IsChecked" Value="False">
                    <Setter Property="IsEnabled" Value="False" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </Grid.Resources>

    <CheckBox IsChecked="True" />
</Grid>

This approach has the benefit of being applied to all (as-is) or many (if you apply a x:Key attribute and then assign the resource to the desired checkboxes) without needing to do anything special or change the bindings of the individual checkboxes.

CodingGorilla
  • 19,612
  • 4
  • 45
  • 65
  • Is it possible to change color of disabled checkbox? Your solution would be good if I could change color of the checkbox's rectangle. I need to have checkbox looking like it was still 'checkable'. – patryk.beza Jun 13 '12 at 19:38
  • Nope, not without implementing your own control template. If you don't want to disable the control, then your only option is going to be to have some code-behind event handler that decides when the checkbox can or can't be checked. – CodingGorilla Jun 13 '12 at 19:49
2

An easy solution could be to bind the IsEnabled property to be equal to the IsChecked property.

Kevin DiTraglia
  • 25,746
  • 19
  • 92
  • 138
  • That's a good solution, because it also gives a visual cue to the user that the checkbox no longer can be used. (Except that it should be IsEnabled and not the opposite. IsReadOnly is only for TextBoxes). –  Jun 13 '12 at 19:23
  • IsReadOnly is not valid property for a wpf checkbox – Nick Babcock Jun 13 '12 at 19:25
  • Checkbox should always be enabled, so that user can think that checkbox can be checked. Maybe it's strange but it's specific programme. – patryk.beza Jun 13 '12 at 19:32
  • @patryk.beza Why can it not be disabled? Can you trick the user into thinking it's enabled by overriding the UI effects of disabling the control? – Kevin DiTraglia Jun 13 '12 at 19:43
0

To make the disabled checkbox visibility similar to enabled one with disabled properties, set the opacity to 0 in triggers

<CheckBox.Resources>
     <Style TargetType="CheckBox">
           <Style.Triggers>
                <Trigger Property="IsEnabled" Value="False">
                      <Setter Property="Opacity" Value="1"/>
                </Trigger>
            </Style.Triggers>
       </Style>
</CheckBox.Resources>
Veeresh S
  • 1
  • 3