Splitters paint issue on Win7 x64 using SCSF & CAB

Topics: CAB & Smart Client Software Factory
Jan 11, 2012 at 8:02 AM

In a form I have some splitters and user controls with grids, buttons, labels... inside this splitters, when the form is opened in runtime, the user controls are not painted correctly, this problem is known for win7 x64 as described here controls inside Split Container paint issue on Windows 7 and here http://www.componentfactory.com/blog/2011/05/deep-nesting-and-redrawing/ . The workaround provided in the above topics consist of overriding the OnSizeChanged method :

protected override void OnSizeChanged(EventArgs e)
   
{
       
if (Handle != null)
           
BeginInvoke((MethodInvoker)delegate
           
{ base.OnSizeChanged(e); });
   
}

the problem with this solution when using the CAB & SCSF that this method is called when initializing form components from constructor (InitializeComponent called from constructor ) and OnLoad method is called when Handle property is accessed because it is created if its value is null,

protected override void OnLoad(EventArgs e)
   
{            
        _presenter
.OnViewReady();
       
base.OnLoad(e);            
   
}

Here the _presenter is not set yet and its value is null and an axception is thrown.

What can I do for this issue?

Regards.

Jan 12, 2012 at 3:34 PM
Edited Jan 12, 2012 at 3:34 PM

Hi,

If I understood your scenario correctly, the problem in this case seems to be how to avoid the NullReferenceException that is thrown when the OnLoad method is invoked as a consequence of the Handle property being accessed in the OnSizeChanged method.

Based on my understanding, as a quick workaround, you could try checking that the _presenter member is not null before accessing the Handle property in the OnSizeChanged method or in the OnLoad method.

Other possible approach would be to use a flag, which would be set after the InitializeComponent method finishes. Then you could check for this flag in the OnSizeChanged method before accessing the Handle property.

I hope you find this useful,

Damian Cherubini
http://blogs.southworks.net/dcherubini

Jan 12, 2012 at 3:56 PM

Hi Damian,

I am using the second approach (using a flag that is set to true after the InintialzeComponent is completed), the falg is tested before testing the Handle property  and this works fine. 

protected override void OnSizeChanged(EventArgs e)
        {
            if (_isComponentsInitCompleted && Handle != null)
                BeginInvoke((MethodInvoker)delegate
                { base.OnSizeChanged(e); });
        }

Thanx for your help and suggestions.

Ragards.