Control disappearing in designer - vb.net

Consider an empty WinForms application created using VS2010.
It has a custom TextBox class with the following code:
Public Class DummyTextBox : Inherits TextBox
Private Const FONT_SIZE As Single = 14.25!
Private Const FONT_FAMILY As String = "Microsoft Sans Serif"
Private Sub Me_ParentChanged(sender As Object,
e As System.EventArgs) Handles Me.ParentChanged
'this one does not work, it causes designer
'to lose its controls once in a while
Me.Font = New Font(Me.Parent.Font.FontFamily, FONT_SIZE)
'if I use a constant value instead, like below, it works fine
'Me.Font = New Font(FONT_FAMILY, FONT_SIZE)
End Sub
End Class
So basically a TextBox with increased font size, same family as the parent form.
What happens is that after being put on the form, and then built, the control sometimes disappears from designer view. If you run the project, it's usually showing fine. Close/reopen a form and it's there again.
Sometimes, however, the control will disappear completely (I was not able to reproduce this 100% of the time), so you'd have to add it again and set the properties. If multiple controls are placed in one shot, usually only one of them disappears like that. Controls are more likely to disappear after being moved around on the form.
What's going on?

According to my research, Me.Parent can sometimes be Nothing inside ParentChanged, so that line throws an exception, which is never displayed to the user (it only happens at design time). Putting a Try/Catch around it helps verify this fact. It looks like Windows Form Designer likes detaching controls and attaching them back at its own discretion.
To solve the problem, need to verify there exists a parent, and only then set the Font.
So changing this:
Me.Font = New Font(Me.Parent.Font.FontFamily, FONT_SIZE)
To this:
Dim parent As Control = Me.Parent
If parent Is Nothing Then Return
Me.Font = New Font(parent.Font.FontFamily, FONT_SIZE)
Makes the issue go away and does not affect runtime in any way.

Related

how to set transparent opacity to panel

how do i set panel transparent like opacity to 0. i set the panel by program and it was on top of video player. the code is like this
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click ', AxVLCPlugin21.Click
Dim panelx As New Panel
panelx.Visible = True
panelx.Size = New Size(AxVLCPlugin21.Width, CInt(AxVLCPlugin21.Height / 2))
panelx.BackColor = System.Drawing.Color.Transparent
AxVLCPlugin21.Controls.Add(panelx)
panelx.BringToFront()
'AddHandler panelx.DoubleClick, AddressOf panelx_click
End Sub
the result is like this
then i try to play the video it only show the half
the reason i use panel is to pause the video (set panel on top of video by transparent), when i click the panel since the video doesn't support click event
update
i put the code in usercontrol1
still got me an error, although i have insert the code in designer. too clarify i put the code designer after below the main designer code. i have tried to put only inherit panel code in main designer code but it only take one inherit only.
The best way to do this is to create a custom control that inherits the panel class and overrides CreateParams and OnPaintBackground with this bit of code:
(Props to Zohar Peled for his post here)
Replace the code behind with:
Public Class TransparentPanel
Inherits System.Windows.Forms.Panel
Protected Overrides ReadOnly Property CreateParams() As CreateParams
Get
' Make background transparent
Dim cp As CreateParams = MyBase.CreateParams
cp.ExStyle = cp.ExStyle Or &H20
Return cp
End Get
End Property
Protected Overrides Sub OnPaintBackground(e As PaintEventArgs)
' call MyBase.OnPaintBackground(e) only if the backColor is not Color.Transparent
If Me.BackColor <> Color.Transparent Then
MyBase.OnPaintBackground(e)
End If
End Sub
End Class
And replace the designer code with:
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
Partial Class TransparentPanel
Inherits System.Windows.Forms.Panel
'Control overrides dispose to clean up the component list.
<System.Diagnostics.DebuggerNonUserCode()>
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
'Required by the Control Designer
Private components As System.ComponentModel.IContainer
' NOTE: The following procedure is required by the Component Designer
' It can be modified using the Component Designer. Do not modify it
' using the code editor.
<System.Diagnostics.DebuggerStepThrough()>
Private Sub InitializeComponent()
components = New System.ComponentModel.Container()
End Sub
End Class
The code you're replacing may look different initially, but using this code will ensure everything works.
NOTE: This code will make the panel transparent if the backcolor is set to Transparent or Control (which depending on the control is normally actually the same as transparent.)
I tried to find an updated resource for creating and implementing a custom control, but I wasn't able to find a maintained resource. So here are some step by step instructions on how to create a custom control.
To create custom control usable in the designer:
(I'm using Visual Studio 2015 for the examples below, it may appear different in other versions.)
1. Create new Windows Forms Control Library
2. Then right click and rename your control to "TransparentPanel" (or
whatever name you like)
3. Paste the code above into the code behind and the designer code respectively (changing the class name if you didn't use "TransparentPanel")
4. Build the project (this will create the .dll you will need to reference in your main project)
5. This one is optional, but it is good to store your DLLs somewhere consistent, other than the project bin folder, so, optionally, navigate to the control library bin folder and copy the created DLL to another location you want to store your custom DLLs.
6. Go to the project you want to use the control in, and right click in the toolbox and click "Choose Items..."
7. Make sure you are on the the ".NET Framework Component" tap and select "Browse".
8. Navigate to the bin folder of the control library (or where ever you stored the DLL), select the control and click "Open".
9. You will see the TransparentControl selected now in the "Choose Toolbox Items" form. Click "OK"
10. Then you should be able to find the control under "General" section.
11. Drag and drop the control onto your form.
NOTE:
The control may not look transparent in the designer, but on runtime it should do what you are looking for.
I hope this works for you!

Enabled but unselectable menu item

In WinForms application I need some "caption" in dynamically created ContextMenuStrip.
That caption is changable text composed in ContextMenuStrip_Opening event handler.
For that purpose I'm trying to use ToolStripControlHost with label in it, like this:
Dim labelItem As ToolStripControlHost = New ToolStripControlHost(New Label)
...
labelItem.BackColor = Color.Transparent
labelItem.ForeColor = Color.FromKnownColor(KnownColor.HotTrack)
labelItem.ToolTipText = "mytooltiptext"
mycontextmenu.Items.Add(labelItem)
That work almost OK, but...
I try to disable that "labelItem" to avoid clicks and keypresses and then it becomes gray automatically what is unwanted and also then tooltiptext is not showed.
If "labelItem" is enabled then color is OK, item cannot be selected with keys but can be with mouse and on mouse click it takes focus to itself. That is also unwanted but shows tooltiptext.
Is here a way in described situation to get "labelItem" to be enabled and able to show tooltiptext but be unselectable? In short... How to make an item like is described which would be in color (enabled) but would not accept mouse clicks and take a focus?
Don't disable the item. Set the disabled state image and then in the click event handler, just ignore the case for the item you don't want to be active.
Enabled and Disabled are predetermined definitions for for the appearance and behavior of a control. Disabled will always mean the control can't be clicked.
If you need alternate behavior, you'll need to write it yourself. I would suggest tracking two global variables in your form: whether or not your item should be active in a boolean and which object currently has focus in an object. Then use these to write your click event behavior. For example:
Public Class Form1
Public RunEvent As Boolean
Public HasFocus As Object
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If RunEvent Then
'Do something
Else
HasFocus.Focus()
End If
End Sub
End Class

VB.NET - Background fade like in the UAC message?

Hello,
When the UAC message is displayed in Windows Vista, 7 or 8 the background becomes inaccessible until the user selects from the message dialog. Can this be done with VB.NET program to make the background inaccessible until the user selects from the Form?
What I want is what happens to the background when UAC or similar message is shown like the image below,
That's pretty easy to do, just display a black borderless form with opacity and the dialog on top of it. Do keep in mind that this of course cannot provide the same level as protection as the UAC prompt provides, you cannot use the secure desktop yourself.
Public Shared Function Plexiglass(dialog As Form) As DialogResult
Using plexi = New Form()
plexi.FormBorderStyle = FormBorderStyle.None
plexi.Bounds = Screen.FromPoint(dialog.Location).Bounds
plexi.StartPosition = FormStartPosition.Manual
plexi.AutoScaleMode = AutoScaleMode.None
plexi.ShowInTaskbar = False
plexi.BackColor = Color.Black
plexi.Opacity = 0.45
plexi.Show()
dialog.StartPosition = FormStartPosition.CenterParent
Return dialog.ShowDialog(plexi)
End Using
End Function
Tweak the Opacity value as desired, the higher the value the darker the background. Looks like this on a little test program:
You are looking for ShowDialog(). This means it will bring the control in front of others and here's a quick example.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim nform As New Form
nform.Text = "Test Form"
nform.ShowDialog()
End Sub
If you use BringToFront() method all this will do is bring it to front in the z-order. Same with TopMost(), but the only difference in TopMost() is that window will always be at top.
Thanks!
MrCodexer

Darken a .Net Form

I have a 1080p touchscreen application. When a modal pops up, i want to emphasize that by darkening the main form.
Right now i use a second form, the size of the main form, that is black and has 50% opacity. Whenever a modal needs to appear, i open the opaque form, and then open the desired modal.
I feel this is a bit devious for my purpose. Its also not asshole-proof that when the user alt tabs, the forms will glitch out of sequence.
Is there a better way to achieve the darkening effect. Perhaps by darkening the main form from within itself?
Solved it myself by doing the following:
Place a hidden picturebox with dock:fill on the main form,
Take a screenshot of the current screen and darken it
assign the image to the picturebox and make it visible
open the modal in a new win
when the modal is dismissed
hide the picturebox
It really stupid that VB.net doesn't have this function built into it. Here's what you do to get around it:
Make a new form and call it Shade. I'm going to assume your main form is called frmMain. For the sake of clarity, lets assume the form you're launching is called dlgX.
Add the following lines in the Load event of dlgX (that's the sub with dlgX.Load or Me.Load or MyBase.Load):
Shade.Opacity = 0.001
Shade.Show()
Shade.Location = frmMain.Location ' Form location will only update if the form is visible.
Shade.Hide()
Shade.FormBorderStyle = Windows.Forms.FormBorderStyle.None 'This gets rid of the windows Titlebar and window border.
Shade.Size = frmMain.Size
Shade.BackColor = Color.Black
Shade.Opacity = 0.5
Shade.Show() ' Form size will only update the next time you show it.
Shade.TopMost = True ' Puts Shade over main form
Me.TopMost = True ' Puts current form over shade
Under all events that dismiss the form dlgX (OK.click, Cancel.click, etc), add the following lines:
Shade.Close
Or you can even make your own sub that handles all events where the form is closed:
Private Sub DispelShades(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Me.FormClosed
Shade.Close()
End Sub
This is way simpler than the PictureBox scenario and you don't have to mess with layering issues and having to ensure that the PictureBox renders on top of everything (for example, tabs really do not like having things rendered above them and they will not let you render a picture box above them). Rendering a black semi transparent form above your main form gets around all these headaches.
If you have multiple forms to shade, just make a Shad1, Shade2, Shade3 etc.
This is pretty obvious but it's worth stating: if you're shading the main form, you'll also want to make it unclickable by opening dlgX via dlgX.ShowDialog and not dlgX.Show
Here is some code, very similar to the method in Thomas's answer. Note to use the Darkness property in a Try...Finally block, to make sure you never leave the form in the dark state.
Public Class Form1
Private _PB As PictureBox
Public WriteOnly Property Darkness
Set(value)
If value Then
Dim Bmp = New Bitmap(Bounds.Size.Width, Bounds.Size.Height)
Me.DrawToBitmap(Bmp, New Rectangle(Point.Empty, Bounds.Size))
Using g = Graphics.FromImage(Bmp)
Dim Brush As New SolidBrush(Color.FromArgb(125, Color.Black))
g.FillRectangle(Brush, New Rectangle(Point.Empty, Bmp.Size))
End Using
_PB = New PictureBox
Me.Controls.Add(_PB)
_PB.Size = Bounds.Size
_PB.Location = Bounds.Location - PointToScreen(Point.Empty)
_PB.Image = Bmp
_PB.BringToFront()
Else
If _PB IsNot Nothing Then
Me.Controls.Remove(_PB)
_PB.Dispose()
End If
End If
End Set
End Property
Private Sub btnDialog_Click(sender As Object, e As EventArgs) Handles btnDialog.Click
Try
Darkness = True
MsgBox("Modal dialog")
Finally
Darkness = False
End Try
End Sub
End Class

vb.net How to get working scrollbars when moving nested form controls inside a parent panel

I have a container (a panel) which can contain multiple Form controls.
(Form.TopLevel = False)
When the user moves the Forms around I would like to display scrollbars when a form is out of the panel bounds.
When I register the Form.Move event, I can set the AutoScrollPosition. This works unless the user uses the scrollbars.
The problem is that the form.move event is also fired when the scrollbars are used. The result is that the scrollbars don't work. (And I have currently no idea how to find out whether the form has been moved by the mouse or by the scrollbar)
So the question is: How can I make the scrollbars of the panel appear/work when a form (or multiple) forms of the panel exceed the boundaries? I think there must be a simpler way than to handle the move event..
Note:
The panel is placed inside a Infragistics DockableControlPane. (Managed by an UltraDockManager)
(So there are multiple panels which contain at least one form per panel)
The reason is that the "panels" should appear as tabs, can be moved around using the DockManager and display their "sub" forms (Which also can be moved around on their panel).
Any idea would be great
It looks like the LocationChanged event could be used. Example with only one form:
Protected Overrides Sub OnLoad(e As EventArgs)
MyBase.OnLoad(e)
Dim f As New Form
f.TopLevel = False
AddHandler f.LocationChanged, AddressOf Form_LocationChanged
Panel1.Controls.Add(f)
f.Show()
Call Form_LocationChanged(f, EventArgs.Empty)
End Sub
Private Sub Form_LocationChanged(sender As Object, e As EventArgs)
With DirectCast(sender, Form)
Panel1.AutoScrollMinSize = New Size(.Bounds.Right, .Bounds.Bottom)
End With
End Sub
Using an MDI form seems to be more appropriate though for something like this.