This limitation is caused by Microsoft code. When the Form.ValidateChildren method is called, it is checked whether or not the Control.ShouldPerformContainerValidation method returns true for a parent control.
For a standard TabControl, this method simply returns true. In the Control class, this method returns true if a control supports the ContainerControl style. So, two options exist: either override the Control.ShouldPerformContainerValidation method, so that it returns true for XtraTabControl, or apply the ContainerControl style to it.
Since the Control.ShouldPerformContainerValidation method is internal, we cannot override it. In addition, XtraTabControl is not a container control. So, we cannot apply the ContainerControl style in our source code.
As a workaround, it is possible to create an XtraTabControl descendant and apply the ContainerControl style to it.
C#public class MyTabControl : DevExpress.XtraTab.XtraTabControl
{
public MyTabControl()
{
this.SetStyle(System.Windows.Forms.ControlStyles.ContainerControl, true);
}
}
Visual BasicPublic Class MyTabControl
Inherits DevExpress.XtraTab.XtraTabControl
Private public Sub New()
SetStyle(System.Windows.Forms.ControlStyles.ContainerControl, True)
End Sub
End Class
This seems more like a poor design decision than something to lay at Microsoft's feet. Windows Forms is the way it is, so third-party controls have to conform to how WinForms does things. To say that the XtraTabControl is not a container is clearly not the case, since it contains pages, and those pages contain controls which we would expect to be have their Validating event called without any special handling. Granted, you have provided a workaround for this, but why make your customers have to stumble across this counter-intuitive behavior (burned up some hours trying to figure this out) and then have to replace it on every form that uses an XtraTabControl? Why not just put the SetStyle call in the XtraTabControl as it is with GroupControl, which validates it's children properly?
Hello Steve,
Let me explain the current behavior. When you call the standard ValidateChildren method, the following code is executed:
public virtual bool ValidateChildren(ValidationConstraints validationConstraints) { if ((validationConstraints < ValidationConstraints.None) || (validationConstraints > (ValidationConstraints.ImmediateChildren | ValidationConstraints.TabStop | ValidationConstraints.Visible | ValidationConstraints.Enabled | ValidationConstraints.Selectable))) { throw new InvalidEnumArgumentException("validationConstraints", (int) validationConstraints, typeof(ValidationConstraints)); } return !base.PerformContainerValidation(validationConstraints); } internal bool PerformContainerValidation(ValidationConstraints validationConstraints) { bool flag = false; foreach (Control control in this.Controls) { if ((((validationConstraints & ValidationConstraints.ImmediateChildren) != ValidationConstraints.ImmediateChildren) && control.ShouldPerformContainerValidation()) && control.PerformContainerValidation(validationConstraints)) { flag = true; } if ((((((validationConstraints & ValidationConstraints.Selectable) != ValidationConstraints.Selectable) || control.GetStyle(ControlStyles.Selectable)) && (((validationConstraints & ValidationConstraints.Enabled) != ValidationConstraints.Enabled) || control.Enabled)) && ((((validationConstraints & ValidationConstraints.Visible) != ValidationConstraints.Visible) || control.Visible) && (((validationConstraints & ValidationConstraints.TabStop) != ValidationConstraints.TabStop) || control.TabStop))) && control.PerformControlValidation(true)) { flag = true; } } return flag; }
Thus, the form traverses through all controls and checks the result of their ShouldPerformContainerValidation() method call. This method has the following implementation:
internal virtual bool ShouldPerformContainerValidation() { return this.GetStyle(ControlStyles.ContainerControl); }
This means that a control will be validated only if its style is ContainerControl. Our XtraTabControl, like a standard TabControl, does not have this style. However, a standard TabControl operates correctly because it overrides the ShouldPerformContainerValidation method as follows:
internal override bool ShouldPerformContainerValidation() { return true; }
However, this method is internal. This means that we cannot do the same at the level of our XtraTabControl. Moreover, we cannot even call the PerformControlValidation method manually because it is private.
That is why a possible workaround for this issue is to set this style to XtraTabControl.
In any case, thank you for sharing your ideas with us. We always appreciate customer feedback.