1

I was trying to add a background image to the tab control

$tc_ASSTabControl.BackgroundImage  = [System.Drawing.Image]::FromFile('C:\Users\me\test\image1.jpg')

Here is the code to define the tab control

# Creating Tab Control 

$tc_ASSTabControl = New-Object System.Windows.Forms.TabControl

# Customizing the ASS Tab Control

$tc_ASSTabControl | ForEach-Object {
    
    $_.DataBindings.DefaultDataSourceUpdateMode = 0
    $_.Location = New-Object System.Drawing.Point(18,  65)
    $_.Name = "tc_ASSTabControl"
    $_.Width = 850
    $_.Height = 580
    $_.BackColor = [System.Drawing.Color]::Transparent

}

When the background image is added, the form flickers when the form is loaded initially and whenever the tab(SelectedIndex of tab control) is changed.

I tried the following option

Setting DoubleBuffered property to true

#This code doesn't work
$form.DoubleBuffered = $true

Here is a relevant thread on How to fix the flickering in User Controls.

The backcolor property of each control was set to "Transparent" by

BackColor = [System.Drawing.Color]::Transparent

Here is the screen capture of the issue. This happens when the form is loaded as well.

enter image description here

Here is an example of how I have defined the label at the top of the first tab, in case that helps to understand the reason for the flickering.

$lbl_BrowseSearchFolder = New-Object system.Windows.Forms.Label -Property @{
    text     = "Browse for the folder that is to be searched"
    AutoSize = $true
    width    = 25
    height   = 10
    location = New-Object System.Drawing.Point(29, (25 + $ySpacer))
    Font     = 'Arial,10'
    BackColor = [System.Drawing.Color]::Transparent
}

As you may see from the image, it's the controls on "Search Criteria" tab that are loaded with a lag. Is there any property of those controls that can be set to prevent this lag in loading?

Could someone suggest a way to fix the flickering issue on PowerShell form

rhythmo
  • 859
  • 2
  • 9
  • 21
  • Would it help if you didn't use a .jpg file, but a .bmp file instead (no compression) – Theo Apr 22 '21 at 13:20
  • @Theo Thanks for the suggestion. I tried replacing it with 24-bit .bmp image. No luck there. – rhythmo Apr 22 '21 at 13:27
  • I think the flickering has to do with the large surface that has to be redrawn while an equally large transparent **label** is put above it. Perhaps you can 'cheat' by not using a label control, but a Panel control instead where you set the background image to be the same image as for the tabcontrol. Make the panel the same size and dock onto the tabcontrol. – Theo Apr 22 '21 at 14:07
  • Thanks for your time. I tried that. I created a panel control and added the tab control on to it and set the background image of panel control after setting tab control BackColor to "Transparent". Sadly, it didn't work – rhythmo Apr 22 '21 at 15:54
  • No, i meant the other way around. Put the panel on top of the tab, instead of the label. Set its background image and not transparent. Its the transparency that creates the problem – Theo Apr 22 '21 at 16:42
  • Right. That's what I tried initially. Got this error "Exception calling "AddRange" with "1" argument(s): "Cannot add 'Panel' to TabControl. Only TabPages can be directly added to TabControls." – rhythmo Apr 22 '21 at 17:25
  • This behavior is not related to generic *Layout*, which involves the positioning of Controls in a container that supports Layout adjustments and Controls that implement `ISupportInitialize`. The problem is that you have set a BackgroundImage to the TabControl, which doesn't exactly support double-bufferring, even when forcibly enabled. You can have a much better result is you double-buffer the Form, add a PictureBox (which is double-buffered *by nature*) to each TabPage, dock it to `Fill` and place other Controls over it. Use the same Image object for all the PictureBoxes you add. – Jimi Apr 23 '21 at 13:12
  • @Jimi I tried setting $form.DoubleBuffered = $true and I got this error "New-Object : The member "DoubleBuffered" was not found for the specified .NET object." Is there another way to enable double buffering for the $form. Thanks – rhythmo Apr 23 '21 at 14:25
  • Yes, that's an *environmental* property, it's not actually available. You need to build your Form in c# code and set `SetStyle(ControlStyles.OptimizedDoubleBuffer, true);` in the Form constructor (build a custom class derived from `Form`). -- I don't remember if you can just write, e.g., `$form = [Form] @{ DoubleBuffered = $true; }` to create the instance and have the property available. – Jimi Apr 23 '21 at 14:57
  • Right, I saw that option for C#. But it's a significant effort to port this code to C# . I suppose I am going to drop the idea of background image temporarily unless you can suggest some option to convert in an easier way. Thanks for the suggestions. – rhythmo Apr 23 '21 at 18:32
  • You can write C# code in Powershell, that's not a problem at all.See [here](https://stackoverflow.com/a/59043639/7444103), for example. You can find many other examples like that. – Jimi Apr 23 '21 at 19:46

1 Answers1

0

I would try to suspend the layout of the form during the operation using SuspendLayout and resume ResumeLayout

The SuspendLayout and ResumeLayout methods are used in tandem to suppress multiple Layout events while you adjust multiple attributes of the control. For example, you would typically call the SuspendLayout method, then set the Size, Location, Anchor, or Dock properties of the control, and then call the ResumeLayout method to enable the changes to take effect.

JPBlanc
  • 70,406
  • 17
  • 130
  • 175
  • Thanks for the suggestion, I added SuspendLayout() for both form and tab control and then executed ResumeLayout() before the ShowDialog(). But sadly, it didn't resolve. I've added a screen capture gif to show what's happening. – rhythmo Apr 22 '21 at 12:02
  • As you may see from the image, it looks like it's the controls on "Search Criteria" tab that are loaded with a lag. Is there any property of those controls that can be set to prevent this lag in loading? – rhythmo Apr 22 '21 at 13:19
  • Nice gif, very explicit!, I'am quite sure You can solve this with SuspendLayout()/ResumeLayout(). You have to put them in the place the controls are loaded. – JPBlanc Apr 22 '21 at 16:26
  • Thanks for your remark. By " place the controls are loaded", do you you mean the place where we add the controls to the tab page ?, i.e., $tp_searchCriteria.controls.AddRange(@( controls... )) I tried adding SuspendLayout() before this execution and ResumeLayout() after this for all the controls. Couldn't fix it though. Thanks for your time anyways. – rhythmo Apr 22 '21 at 17:20