Unfortunately the dataform that was shipped with Silverlight 3 RTW (in the Toolkit) was massively changed from the beta version, and as a result has a number of bugs that were not there during the beta.
To find these bugs create a new project using the business application template, and run it. Click login, type some text into Username and then click OK and you will see the following screen:
You will note that there are two problems with this screen:
1. the first one is that the data form has become opaque
2. the second one is the fact that the password and confirm password, which are required fields are not marked in red.
3. If you add in a checkbox as a label and click OK, you get this screen:
Workarounds
1. This bug is caused because the DataForm doesn’t listen for IsEnabledChanged, but in the UpdateStates() function will call GoToState to change for the disabled state. Unfortunately if it doesn't go back and to update states after if you enable, you're left in the disabled state. The workaround is to create a derived class that looks like this and use it in place of the dataform:
public class LessBuggyDataForm:DataForm
{
private const string DATAFORM_stateDisabled = "Disabled";
private const string DATAFORM_stateNormal = "Normal";
public override void OnApplyTemplate()
{
IsEnabledChanged += LessBuggyDataForm_IsEnabledChanged;
base.OnApplyTemplate();
}
void LessBuggyDataForm_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if (!IsEnabled)
{
VisualStateManager.GoToState(this, DATAFORM_stateDisabled, true);
}
else
{
VisualStateManager.GoToState(this, DATAFORM_stateNormal, true);
}
}
}
2. I'm not entirely sure why this bug is caused. What happens is that unless the password text is updated, the validation doesn't seem to occur. Therefore, the workaround is every time you want to force validation to happen. You need to call a function like this in the password control:
public void UpdatePasswordText()
{
this.PasswordText = this.password.Password;
}
Normally you'd call this before you call ValidateItem() or CommitEdit()
3. This problem is caused by the fact that when you click the okay button, CancelEdit() is called, which completely rebuilds the label. The exception is because checkbox is already the child of another control, and it tries to make it a child of the new label.
The workaround is to stop the ability to cancel the editing like this:
registerForm.EditEnding += new EventHandler<DataFormEditEndingEventArgs>(registerForm_EditEnding);
}
void registerForm_EditEnding(object sender, DataFormEditEndingEventArgs e)
{
if (e.EditAction==DataFormEditAction.Cancel)
{
e.Cancel = true;
return;
}
}
Hopefully these solutions will save someone else some time.
…Stefan