Saturday, April 30, 2011

Split Personality of a Silverlight Control

Silverlight control visual states are separate from their enabled/disabled states. For example, a DataForm control can be enabled and yet shown in a “Disabled” visual state. I don’t know why these two states would ever need to be separated. It can only cause confusion.


When a Silverlight Control Toolkit ChildWindow is opened from a command bound to a button inside a DataForm control, this DataForm control is disabled, and its visual state becomes “Disabled” as well. However, when the ChildWindow is closed and the DataForm control is re-enabled, its visual state remains in “Disabled”.


If you did not expect this behavior, you would probably think that the DataForm control is still disabled after the ChildWindow is closed. Well it is enabled. It is just not rendered that way. There is an article here that suggested we create a derived control that updates the visual states in an event handler. It is a good solution, but of course, you can handle the state change anywhere, such as in a parent control’s code:



private void MyDataForm_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if(MyDataForm.IsEnabled)
{
VisualStateManager.GoToState(MyDataForm, "Normal", true);
}


else
{
VisualStateManager.GoToState(MyDataForm, "Disabled", true);
}


}



The fix is easy once you know what the bug is.