3

This is a bit of a wierd problem. (.NET 3.5sp1)

I have a UserControl containing three ToggleButtons, each with IsChecked bound to different dependency properties on the UserControl itself. Two of these default to true, one defaults to false.

On startup of the application, the UserControl itself (and thus its contents) is disabled. When it gets enabled later on, all three buttons appear un-pressed; however the code properties are still in the correct state.

If the buttons are clicked then the properties will toggle properly and the UI (for that button only) will update to reflect the correct state (ie. clicking on a button which appears un-pressed but has a true bound value will show no visible change the first time, but updates the bound value to false). Pressing a "glitched" button for the second time will behave normally (if it toggles on, the button will press in as expected).

If the UserControl is not disabled on startup, then the buttons will appear correctly (according to the state of the properties).

Unfortunately the UserControl is supposed to be disabled on startup, so I can't really start up with it enabled; I'm hoping for an alternate solution. Any ideas?

(I've tried making the properties default to false and then setting them to true in the user control's Load event. Doesn't make any difference.)

Miral
  • 12,637
  • 4
  • 53
  • 93

2 Answers2

2

The same weird problem happens in .NET 4.0 as well. I noticed that the problem only occurs if you set IsEnabled through code and not if you bind it, so if you can change your code to that instead I believe your problem will be solved.

Otherwise, I believe a workaround is necessary and here is one way to do it. Reset the DataContext for the UserControl the first time IsEnabled is set to True.

public UserControl1()
{
    InitializeComponent();

    DependencyPropertyDescriptor descriptor =
        DependencyPropertyDescriptor.FromProperty(UserControl1.IsEnabledProperty, 
                                                  typeof(UserControl1));
    EventHandler isEnabledChanged = null;
    isEnabledChanged = new EventHandler(delegate
    {
        if (IsEnabled == true)
        {
            descriptor.RemoveValueChanged(this, isEnabledChanged);
            var dataContext = this.DataContext;
            this.DataContext = null;
            this.DataContext = dataContext;
        }
    });
    descriptor.AddValueChanged(this, isEnabledChanged);
}
H.B.
  • 166,899
  • 29
  • 327
  • 400
Fredrik Hedblad
  • 83,499
  • 23
  • 264
  • 266
  • Actually I might have oversimplified -- IsEnabled is data bound, but not directly on the user control, it's on an element higher up the tree. But this hack did work, after making it adjust the correct DataContext (I always put internal contexts on the first child, not on the UserControl itself. Otherwise they can get overridden from outside, which gets messy.) – Miral Feb 11 '11 at 04:47
0

I came across a 'somewhat' similar situation and the following SO reply proved to be more appropriate in my case. It save me a lot of troubles and so, just in case anyone looking at this solution hasn't noticed it, I think a reference to it should be useful here.

WPF ToggleButton incorrect render behavior

Cheers

Mansoor

Community
  • 1
  • 1
man.kar
  • 125
  • 2
  • 9