简体   繁体   中英

How can I modify the visual state of a disabled checkbox to look enabled?

I am designing a comparison dialog (shows several widgets with their characteristics in a grid). There is a features section where all available features are listed with a check box for each one. If the part has that feature, the checkbox is checked. These checkboxes need to be read-only so I've isEnabled=false. However visually the checkboxes (and the label content) show as greyed out.

Here are some important points:

  • The checkbox is a visual indicator of whether a part has a feature. There is no requirement for interaction.
  • The requirement is for a checkbox; I'd have to convince the powers that be to use something different.

What I want is an easy way to style/controltemplate a checkbox (and it's content) so it looks enabled, but doesn't react to user input.

Create a custom control by inheriting from CheckBox, and in its constructor create a Click handler for it. Within that Click handler, put the following code:

((CheckBox)sender).Checked = !((CheckBox)sender).Checked;

Here's a complete example.

For Windows Forms:

namespace System.Windows.Forms
{
    public class UnChangingCheckBox : System.Windows.Forms.CheckBox
    {
        public UnChangingCheckBox()
        {
            this.Click += new EventHandler(UnChangingCheckBox_Click);
        }

        void UnChangingCheckBox_Click(object sender, EventArgs e)
        {
            ((CheckBox)sender).Checked = !((CheckBox)sender).Checked;
        }
    }
}

For WPF:

namespace System.Windows.Controls
{
    public class UnchangingCheckBox : System.Windows.Controls.CheckBox
    {
        public UnchangingCheckBox()
        {
            this.Click += new System.Windows.RoutedEventHandler(UnchangingCheckBox_Click);
        }

        void UnchangingCheckBox_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            if (((CheckBox)sender).IsChecked.HasValue)
                ((CheckBox)sender).IsChecked = !((CheckBox)sender).IsChecked; 
        }
    }
}

If you place the above code in a new class in your Windows Forms or WPF project, they'll appear as new tools in your toolbox. Then all you need to do is drag your new "UnchangingCheckBox" control onto your form where you were using a CheckBox. You don't need to do any coding on your form.

Using this approach your code will still be able to do everything you could do to a CheckBox (set its value, etc). It's only user interaction that's been disabled in a way that doesn't interfere with the visual style.

Microsoft provides some of their default styles on MSDN and you can find the default style for a checkbox here: http://msdn.microsoft.com/en-us/library/ms752319(v=vs.85).aspx . Copy this style into your project, remove the Trigger for IsEnabled and set the style for your checkboxes to this new style.

On a side note, I'd recommend copying the style into a separate ResourceDictionary for reusablitiy and to keep the style from cluttering up your xaml files.

The solution suggested above works well for Windows Forms, but I see what you mean about WPF and the check mark appearing for a second.

Try this instead:

namespace System.Windows.Controls
{
    public class UnchangingCheckbox : CheckBox
    {
        public UnchangingCheckbox()
        {
            this.IsReadOnly = true;
        }

        public bool IsReadOnly 
        {
            get { return !this.IsHitTestVisible && !this.Focusable; }
            set 
            { 
                this.IsHitTestVisible = !value; 
                this.Focusable = !value;             
            }
        }
    }
}

You acquire a property called "IsReadOnly", which by default is set to true, and has the behaviour you require without the annoying "checkmark appears for a second" behaviour.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM