CefSharp inside a Control - vb.net

When I attempt to add CefSharp to a Panel or Groupbox it doesn't display anything (by that I mean that the webbrowser doesn't show, even a blank page, only the control background is visible as if there is nothing added).
But when I use "Me" instead, it works normally. Why is that? Is it not possible to add it to wherever you want?
Public Class Form_Main
Private WithEvents chromeBrowser As ChromiumWebBrowser
Public Sub InitializeChromium()
InitializeComponent()
Dim CEF_settings As New CefSettings With {
.CachePath = "Cache"
}
CefSharp.Cef.Initialize(CEF_settings)
chromeBrowser = New ChromiumWebBrowser("www.google.com") With {
.Dock = DockStyle.Fill
}
Panel1.Controls.Add(chromeBrowser) 'With Me.Controls.Add(chromeBrowser) it works
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
InitializeChromium()
End Sub
End Class

I don't know why, but changing the Method name to "New" fixes it.
So instead of
Public Sub InitializeChromium()
'Stuff"
End Sub
it must be
Public Sub New()
'Stuff"
End Sub
Now the webbrowser gets displayed no matter where it's placed.

At your Program, You must not to use InitializeComponent().
Remove it from all of the codes.

Related

How to access parent form properties from a child form in vb.net

I have pretty much the same problem as described in this, but using VB.NET. There is a Form1 which is opened automatically as start window, so I cannot find the instance to use for accessing it. There is a Form2 opened from within Form1. I try to pass the instance of Form1 using keyword "Me":
Private Sub Button1_click(...) Handles Button1.Click
Dim childform as new Form2(Me)
childform.show()
End Sub
In Form2 I have:
Public Sub New(parentform As System.Windows.Forms.Form)
InitializeComponents()
MessageBox.Show(parentform.Button1.Text)
End Sub
Upon compiling I get the error: "Button1 is not a member of Form".
So how to pass the Form1 instance correctly to Form2?
Also I want to change some properties of the Button1 of Form1 from Form2. Button1 is declared in a Private Sub, will I nevertheless be able to access it from Form2 if I pass the instance correctly? If not, can I declaring a sub in Form1, e.g.
Public Shared Sub ChangeText(newtext As Sting)
Me.Button1.Text=newtext
End Sub
that will do the job?
I'm not 100% sure about what you are trying to achieve, but, you can pass data between forms. So for example you can do something like:
Public Class Form1
Private Sub Button1_click(...) Handles Button1.Click
Dim newForm2 as New Form2()
newForm2.stringText = ""
If newForm2.ShowDialog() = DialogResult.OK Then
Button1.Text = newForm2.stringText
End If
End Sub
End Class
And in Form2 you have
Public Class Form2
Dim stringText as string
Private Sub changeStringText()
'your method to change your data
Me.DialogResult = DialogResult.OK 'this will close form2
End Sub
End Class
I hope this is what you need, if not let me know
Thanks for your answer and comment. So I declared the wrong class for the parentform, means in Form2 it needs to be "parentform as Form1":
Public Sub New(parentform As Form1)
InitializeComponents()
MessageBox.Show(parentform.Button1.Text)
End Sub
and yes, I need to skip the "shared" in the ChangeText:
Public Sub ChangeText(newtext As Sting)
Me.Button1.Text=newtext
End Sub
This way it worked for me.

Access in UserControl Member's Properties

I create a UserControl with three Panels
I add this UserControl in my main Form but i have then the problem that i can't choose which panel to appear in my main form.
Exccactly i have this code below to make visible my Panel1
Public Function Pan1()
Panel3_Paint.Visible = False
Panel2_Paint.Visible = False
Panel1_Paint.Visible = True
Return 0
End Function
So after i click in a stripMenu i tried to appear the first panel with this function in my Form but finally in my main Form appears the third Panel.
i use my function in this way
Private Sub ClassAToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ClassAToolStripMenuItem.Click
UserControl11.Visible = True
Call Pan1()
End Sub`
I try when i click a specific button in menu to show the appropriate panel
That's why i try to do it with this function but i have the problem that in my form appears only the third panel.
My UserControl Code
Public Class UserControl1
Public Sub Panel3_Paint(sender As Object, e As PaintEventArgs) Handles Panel3.Paint
End Sub
Public Sub Panel2_Paint(sender As Object, e As PaintEventArgs) Handles Panel2.Paint
End Sub
Public Sub Panel1_Paint(sender As Object, e As PaintEventArgs) Handles Panel1.Paint
End Sub
End Class
I define also my UserControl and Panels in my Form.vb this way
Public UserControl1 As New UserControl
Public Panel1_Paint As New Panel
Public Panel2_Paint As New Panel
Public Panel3_Paint As New Panel
Without seeing more of your code, I am assuming there may be an issue with the call of the function.
Make sure the function is called in an event. For example, if you add a CommandButton to the Form, you can add the following code to run in case of a click on the button:
Private Sub CommandButton1_Click()
Call Pan1
End Sub
I hope this helps.
So my problem is solved. I can't access in Panel Properties, that's why i create a Public Sub in my UserControl.vb and use it in my Form.
This code is written in my UserControl.vb
Public Sub Pan1()
Panel3_Paint.Visible = False
Panel2_Paint.Visible = False
Panel1_Paint.Visible = True
End Function
And then i call my Sub in my Form in this way
Private Sub ClassAToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ClassAToolStripMenuItem.Click
UserControl11.Visible = True
UserControl11.Pan1()
End Sub

How to call a Sub without knowing which form is loaded into panel?

On every DataGridView1_SelectionChanged event I need to run a Private Sub OnSelectionChanged() of the form that is loaded into Panel1 (see the image http://tinypic.com/r/2nu2wx/8).
Every form that can be loaded into Panel1 has the same Private Sub OnSelectionChanged() that initiates all the necessary calculations. For instance, I can load a form that calculates temperatures or I can load a form that calculates voltages. If different element is selected in the main form’s DataGridView1, either temperatures or voltages should be recalculated.
The problem is - there are many forms that can be loaded into Panel1, and I’m struggling to raise an event that would fire only once and would run the necessary Sub only in the loaded form.
Currently I’m using Shared Event:
'Main form (Form1).
Shared Event event_UpdateLoadedForm(ByVal frm_name As String)
'This is how I load forms into a panel (in this case frm_SCT).
Private Sub mnu_SCT_Click(sender As Object, e As EventArgs) Handles mnu_SCT.Click
frm_SCT.TopLevel = False
frm_SCT.Dock = DockStyle.Fill
Panel1.Controls.Add(frm_SCT)
frm_SCT.Show()
Var._loadedForm = frm_SCT.Name
RaiseEvent event_UpdateLoadedForm(Var._loadedForm)
End Sub
‘Form that is loaded into panel (Form2 or Form3 or Form4...).
Private WithEvents myEvent As New Form1
Private Sub OnEvent(ByVal frm_name As String) Handles myEvent.event_UpdateLoadedForm
‘Avoid executing code for the form that is not loaded.
If frm_name <> Me.Name Then Exit Sub
End Sub
This approach is working but I’m sure it can be done way better (I'd be thankful for any suggestions). I have tried to raise an event in the main form like this:
Public Event MyEvent As EventHandler
Protected Overridable Sub OnChange(e As EventArgs)
RaiseEvent MyEvent(Me, e)
End Sub
Private Sub DataGridView1_SelectionChanged(sender As Object, e As EventArgs) _
Handles DataGridView1.SelectionChanged
OnChange(EventArgs.Empty)
End Sub
but I don't know to subscribe to it in the loaded form.
Thank you.
Taking into account Hans Passant’s comments as well as code he posted in related thread I achieved what I wanted (see the code below).
Public Interface IOnEvent
Sub OnSelectionChange()
End Interface
Public Class Form1
' ???
Private myInterface As IOnEvent = Nothing
' Create and load form.
Private Sub DisplayForm(frm_Name As String)
' Exit if the form is already displayed.
If Panel1.Controls.Count > 0 AndAlso _
Panel1.Controls(0).GetType().Name = frm_Name Then Exit Sub
' Dispose previous form.
Do While Panel1.Controls.Count > 0
Panel1.Controls(0).Dispose()
Loop
' Create form by its full name.
Dim T As Type = Type.GetType("Namespace." & frm_Name)
Dim frm As Form = CType(Activator.CreateInstance(T), Form)
' Load form into the panel.
frm.TopLevel = False
frm.Visible = True
frm.Dock = DockStyle.Fill
Panel1.Controls.Add(frm)
' ???
myInterface = DirectCast(frm, IOnEvent)
End Sub
Private Sub DataGridView1_SelectionChanged(sender As Object, e As EventArgs) _
Handles DataGridView1.SelectionChanged
' Avoid error if the panel is empty.
If myInterface Is Nothing Then Return
' Run subroutine in the loaded form.
myInterface.OnSelectionChange()
End Sub
End Class
One last thing – it would be great if someone could take a quick look at the code (it works) and confirm that it is ok, especially the lines marked with “???” (I don’t understand them yet).

VB.NET Absolutely strange form load behaviour

I am experiencing a strange behaviour when using RightToLayout layout:
My form automatically closes.
I have created a simple project to reproduce the problem:
Create a new VB.NET project in VS2012 and add forms "Form1" and "Form2" to it.
Set "Form1" to be the start form.
Then add the following code to "Form1":
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
Me.Hide()
Dim f As New Form2
f.ShowDialog()
MessageBox.Show("After dialog closed.")
modControls.setFormRTL(Me) 'This line causes the Form2 to automatically close. Why??? This line should only be processed AFTER the dialog has been shown and closed
End Sub
End Class
Add the following code to "Form2":
Public Class Form2
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles Me.Load
modControls.setFormRTL(Me)
End Sub
End Class
Add a module with the name "modControls" to the project.
Add the following code to it:
Module modControls
Public Sub setFormRTL(ByVal uForm As Form)
uForm.RightToLeft = RightToLeft.Yes
End Sub
End Module
Without the setFormRTL, my project works perfectly fine, but with it, "Form2" automatically closes down. You can see this because the messagebox is shown.
When I remove the line
modControls.setFormRTL(Me)
from Form1 load, it works fine again.
Yes, I really mean from "Form1", not from "Form2"!!!
Now this is really strange because it should not matter at all because this line is not processed before the dialog is closed.
I hope somebody understands what I mean.
Can anybody shed some light on what might be happening here?
Yes, you'll get unexpected behavior if you set the RightToLeft property anywhere other than a control's constructor (in VB.NET parlance, that's the New method).
In fact, the constructor is where you should set all of the properties of a form or control object. If you come from VB 6, it might seem logical to do it in the Load event handler, but that's not idiomatic .NET and, as you've discovered, can cause problems when initializing certain properties.
The technical reason for this is that certain properties (like RightToLeft) can actually only be set on the native window (which is how the Form objects used in the .NET world are implemented behind the scenes) at the time that it is created. When you attempt to change the property, the framework code actually has to destroy and then re-create the native window with the new property values.
Change the code to look like this instead:
Public Class Form1
Public Sub New()
MyBase.New()
'This call is required by the Windows Form Designer.
InitializeComponent()
modControls.SetFormRtl(Me)
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
Me.Hide()
Dim f As New Form2
f.ShowDialog()
MessageBox.Show("After dialog closed.")
End Sub
End Class
Public Class Form2
Public Sub New()
MyBase.New()
'This call is required by the Windows Form Designer.
InitializeComponent()
modControls.SetFormRtl(Me)
End Sub
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles Me.Load
End Sub
End Class
Speaking of non-idiomatic .NET code:
Methods should all be Pascal cased by convention. That means your setFormRTL method should be named SetFormRtl.
A helper function that sets the properties of an object just seems wrong to me. If anything, that's just bad OO design. If you want this method to be available for all of your Form objects, derive a custom form class and add this method (or even do the desired initialization in the constructor). Either way, all forms that you derive from this custom form object will inherit the functionality. Example:
Public Class MyCustomForm : Inherits System.Windows.Forms.Form
Public Sub New()
MyBase.New()
Me.SetRtl()
End Sub
Public Sub SetRtl()
Me.RightToLeft = RightToLeft.Yes
End Sub
End Class
Public Class Form1 : Inherits MyCustomForm
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
Me.Hide()
Dim f As New Form2
f.ShowDialog()
MessageBox.Show("After dialog closed.")
End Sub
End Class
Public Class Form2 : Inherits MyCustomForm
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles Me.Load
End Sub
End Class
can you try this? all i am doing here is setting the RTL before the form is displayed.
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
Me.Hide()
Dim f As New Form2
modControls.setFormRTL(f)
f.ShowDialog()
MessageBox.Show("After dialog closed.")
modControls.setFormRTL(Me)
End Sub
End Class
and remove code form load event of form 2

One button to control another button on many user controls

Hey and sorry for another strange question...
I have 25 UserControls with a Start_Button on each of them - this Start_Button can either be Visible or not depending on whether the UserControl is active. On my form1 I have a Start_All button.
I would like to simulate a click of all the UserControl's Start_Buttons which are visible only.
Instead of simulating click-events expose a method for the start-functionality and call this method from the Start_Button.Click-event. Then you can use this method from wherever you want. On this way your code remains readable and reusable.
You should also provide an Active property in your UserControl which you can simply link to your start-button's Visible-property.
Presuming that the user-controls are in a container-control like Panel:
Public Sub StartAll()
Dim allActiveUserControls =
From uc In controlPanel.Controls.OfType(Of MyUserControlType)()
Where uc.Active
For Each uc In allActiveUserControls
uc.Start()
Next
End Sub
Here is an example for the Active property:
Public Property Active As Boolean
Get
Return StartButton.Visible
End Get
Set(value As Boolean)
StartButton.Visible = value
End Set
End Property
and here are the Start method and the event-handlers:
Public Sub Start()
' Do Something ... '
End Sub
Private Sub StartButton_Click(sender As System.Object, e As System.EventArgs) Handles StartButton.Click
Start()
End Sub
Private Sub Start_All_Click(sender As System.Object, e As System.EventArgs) Handles Start_All.Click
StartAll()
End Sub