TtT23
TtT23

Reputation: 7030

Style disabled components in datagrid

I'd like to get rid of the grey-fading out behavior of datagrid cells (Checkboxes, Timepicker, comboboxes etc) when they have been set to disabled.

enter image description here

So this is what I'm trying to do:

<Style TargetType="DataGridCell">
    <Style.Triggers>
        <Trigger Property="IsEnabled" Value="False">
            <Setter Property="Foreground" Value="{x:Null}" />
            <Setter Property="Background" Value="{x:Null}" />
            <Setter Property="BorderBrush" Value="{x:Null}" />
        </Trigger>
    </Style.Triggers>
</Style>

But it doesn't work.

Do I need to define the styles individually for the controls that's actually inside the datagridcell (Checkboxes, comboboxes etc)? What's a good way of making this work?

Upvotes: 3

Views: 990

Answers (1)

Anatoliy Nikolaev
Anatoliy Nikolaev

Reputation: 22702

Firstly, the fact is that the property IsEnabled hard-coded in certain control, so setting properties such as Background impossible, because the color hardcoded in the control. For example - Background in: ComboBox, TextBox, etc. Therefore, in such cases, create styles and templates, overriding the default behavior of the control (in our case: IsEnabled=False behavior).

Secondly, what control in the assigned property DataTemplate IsEnabled like this:

<DataGridTemplateColumn x:Name="ComboBoxColumn" Header="ComboBox Header" Width="110">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <ComboBox IsEnabled="False" />
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

Not to say that DataGridCell will be False, therefore, the trigger will not fire:

<Style.Triggers>
    <Trigger Property="IsEnabled" Value="False">
        <Setter Property="Foreground" Value="Black" />
    </Trigger>
</Style.Triggers>

Hence the conclusion:

Determine the behavior of the control when it is enabled false. Styles for each control can be taken from MSDN.

Example style for CheckBox (link):

<Style x:Key="{x:Type CheckBox}" TargetType="CheckBox">
    <Setter Property="SnapsToDevicePixels" Value="true"/>
    <Setter Property="OverridesDefaultStyle" Value="true"/>
    <Setter Property="FocusVisualStyle" Value="{StaticResource CheckBoxFocusVisual}"/>

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="CheckBox">
                <BulletDecorator Background="Transparent">
                    <BulletDecorator.Bullet>
                        <Border x:Name="Border" Width="13" Height="13" CornerRadius="0" Background="{StaticResource NormalBrush}" BorderThickness="1" BorderBrush="{StaticResource NormalBorderBrush}">
                            <Path Width="7" Height="7" x:Name="CheckMark" SnapsToDevicePixels="False" Stroke="{StaticResource GlyphBrush}" StrokeThickness="2" Data="M 0 0 L 7 7 M 0 7 L 7 0" />
                        </Border>
                    </BulletDecorator.Bullet>

                    <ContentPresenter Margin="4,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Left" RecognizesAccessKey="True" />
                </BulletDecorator>

                <ControlTemplate.Triggers>
                    <Trigger Property="IsChecked" Value="false">
                        <Setter TargetName="CheckMark" Property="Visibility" Value="Collapsed"/>
                    </Trigger>

                    <Trigger Property="IsChecked" Value="{x:Null}">
                        <Setter TargetName="CheckMark" Property="Data" Value="M 0 7 L 7 0" />
                    </Trigger>

                    <Trigger Property="IsMouseOver" Value="true">
                        <Setter TargetName="Border" Property="Background" Value="{StaticResource DarkBrush}" />
                    </Trigger>

                    <Trigger Property="IsPressed" Value="true">
                        <Setter TargetName="Border" Property="Background" Value="{StaticResource PressedBrush}" />
                        <Setter TargetName="Border" Property="BorderBrush" Value="{StaticResource PressedBorderBrush}" />
                    </Trigger>                           

                    <!-- Here set the some properties there IsEnabled will be false -->
                    <Trigger Property="IsEnabled" Value="False">
                        <Setter TargetName="Border" Property="Background" Value="Red" />
                        <Setter TargetName="Border" Property="BorderBrush" Value="Green" />
                        <Setter Property="Foreground" Value="Orange"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>               

I have defined the attached DependencyProperty for a column that shows whether it is turned off. Thereafter, each control in the template column is referenced like that:

<DataGridTemplateColumn x:Name="CheckBoxColumn" local:MyDependencyClass.IsEnabledColumn="False" Width="110" Header="CheckBox Header">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <CheckBox Content="My CheckBox" IsEnabled="{Binding Source={x:Reference Name=CheckBoxColumn}, Path=(local:MyDependencyClass.IsEnabledColumn)}" IsChecked="False" />
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

Set the property IsEnabledColumn, you can set for those controls that you want to disable (IsEnabled=False).

Listing of MyDependencyClass:

public class MyDependencyClass : DependencyObject
{
    public static readonly DependencyProperty IsEnabledColumnProperty;

    public static void SetIsEnabledColumn(DependencyObject DepObject, bool value)
    {
        DepObject.SetValue(IsEnabledColumnProperty, value);
    }

    public static bool GetIsEnabledColumn(DependencyObject DepObject)
    {
        return (bool)DepObject.GetValue(IsEnabledColumnProperty);
    }

    static MyDependencyClass()
    {
        PropertyMetadata MyPropertyMetadata = new PropertyMetadata(false);

        IsEnabledColumnProperty = DependencyProperty.RegisterAttached("IsEnabledColumn",
                                                            typeof(bool),
                                                            typeof(MyDependencyClass),
                                                            MyPropertyMetadata);
    }        
}

P.S. Don't worry about {x:Reference} warning message, it can be ignored.

Upvotes: 1

Related Questions