Switching between forms (VB.NET) - vb.net

I always get an exception when I try to switch between different forms in my program. Maybe you will help me to solve this issue. Here is the exception message:
Control.Invoke must be used to interact with controls created on a separate thread
I have attached the forms to very nice variables and this problem occurs when I try to use command like MyForm.Show().
It does not happen when the forms are not attached to variables, but then I have collosal problems with refreshing the textboxes and stuff.
Hope to hear you soon!
edit;
I have 4 different forms. When I load the main module and main form, in the Sub (...) Handles MyBase.Load I execute the following code:
In module:
Public StartupForm As frmStartup
Public RegularForm As frmRegularUse
Public LoginForm As frmLogin
Public PasswordForm As frmPassword
Public SettingsForm As frmSettings
In main form:
RegularForm = Me
StartupForm = frmStartup
LoginForm = frmLogin
PasswordForm = frmPassword
SettingsForm = frmSettings
This is the aproach I worked out to get the full control over refreshing the forms. It is a program for Motorola Scanner with Windows CE. Now, for example, when I enter the correct password in LoginForm, I want to switch to the RegularForm. When I try to use RegularForm.Show() or RegularForm.ShowDialog or RegularForm.BringToFront(), I get an exception. When I try to call the form with the frmRegularUse.Show() I can call the form, but it is being created in a different thread, I believe, so I loose control over it (when I try to put something from the keyboard, there is no response).

I doubt the forms are getting created in a different thread, but if they are then STOP, go back, and fix that. All of your forms should be created and accessed from the main GUI thread. Secondly, I don't think you "newed" the forms. You need something like this:
StartupForm = New frmStartup
RegularForm = New frmRegularUse
LoginForm = New frmLogin
PasswordForm = New frmPassword
SettingsForm = New frmSettings

Actually, what I did is:
Still I have the same code in the main module, which is:
Public StartupForm As frmStartup
Public RegularForm As frmRegularUse
Public LoginForm As frmLogin
Public PasswordForm As frmPassword
Public SettingsForm As frmSettings
I managed it to work in the simpliest possible way. For example - I run the Login form, and execute the following code (long story short):
LoginForm = Me
frmRegularUse.ShowDialog()
I jump to the frmRegularUse form, where, once again, I execute:
RegularForm = Me
frmPasswordForm.ShowDialog()
And so on...
I made some tests and it works quite okay. Tomorrow I will try to make it a little bit more sophisticated. ;-)

Related

Visual Studio is not letting me add CefSharpBrowserControl to a form via the designer

So I decided to try out the CefSharp extension, and what's the first thing I encounter? An error that doesn't let me use the add-on.
This is ridiculously frustrating because I've done every single thing even the administrator or creator has said to do on any forum I've been on. I tried to just compile the source code on the CEFSharp's GitHub, but that didn't work.
If I'm brutally honest, I think that they should just provide a pre-compiled .dll file or group of .dll files that you can just add to the references, instead of just expecting you to do it yourself. It's just a pain, CEFSharp.
I've tried putting the Configuration to x64 AND Any CPU. I've tried making references to several different dlls associated to CEFSharp. I've tried to add the browser element programmatically, and that's worked, but I can't do anything with it (such as execute code when the webpage is done loading). So far none of these solutions have worked at all.
Imports CefSharp
Imports CefSharp.WinForms
Public Class Browser
Dim browser As New _
CefSharp.WinForms.ChromiumWebBrowser("https://google.com/")
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles _
MyBase.Load
Me.Controls.Add(browser)
browser.Parent = Panel1
browser.Dock = DockStyle.Fill
End Sub
End Class
Any time I want to add the browser control to my form via the designer toolbox, it won't let me. It keeps showing this error box that says "Failed to load CefSharpBrowser, deleting from the toolbox." Or something along those lines. It's supposed to just be able to drop into the designer, but it's obviously not.
There are similar discussions on CefSharp's google group: Adding CefSharp control to the toolbox and The name "WebView" does not exist in the namespace.
They say that Visual Studio has some limitations when using a mixed mode (C++/CLR) assembly. There is no Visual Studio designer support out of the box in CefSharp. There is some hack about how to do it, but I do not think it worth it to even spend time on it. Most people just accept the fact and move on.
We successfully use CefSharp for one of our projects and we add ChromiumWebBrowser control to a form programmatically, very similar to how you did it in your sample.
I've tried to add the browser element programmatically, and that's
worked, but I can't do anything with it (such as execute code when the
webpage is done loading). So far none of these solutions have worked
at all.
There is a LoadingStateChanged event which you can use to monitor the status of a web browser control. We use it to show progress indication until our web page is fully loaded. Here is how we do it:
private System.Windows.Forms.PictureBox picProgress;
bool loaded = false;
ChromiumWebBrowser browse;
public Main()
{
var uiUrl = "some url or local html file";
browse = new ChromiumWebBrowser(uiUrl);
browse.Dock = DockStyle.Fill;
Controls.Add(browse);
browse.LoadingStateChanged += Browse_LoadingStateChanged;
}
private void Browse_LoadingStateChanged(object sender, LoadingStateChangedEventArgs e)
{
if (!e.IsLoading)
{
picProgress.BeginInvoke((Action)(() => {
loaded = true;
picProgress.Visible = false;
browse.Visible = true;
}));
}
else
{
browse.BeginInvoke((Action)(() => {
loaded = false;
browse.Visible = false;
}));
}
}
Sorry, it is in C#, but I think you can easily adapt it for VB.net.

Access label control from masterpage throws nullreferenceexception

enter code hereI am trying to assign a value to label in a Master Page using vb.net (not my first language-lol). I have followed info from these two references on how to access content from masterpage:
1.[https://msdn.microsoft.com/en-us/library/c8y19k6h(v=vs.90).aspx][1]
2.[nullreferenceexception was unhandled by user code in Master Page
I am getting Null Reference Exception on BUT ONLY when I try to call the method I created for it from another class. It works fine when I call it from the same class the method is in. I wrote a method from the starting page/class, WebForm1:
Public Sub PageIdentity(ByVal pageId As String)
' Gets a reference to a Label control inside a ContentPlaceHolder
Dim mpContentPlaceHolder As ContentPlaceHolder
'Dim mpTextBox As TextBox
Dim mpLabel As Label
mpContentPlaceHolder = CType(Master.FindControl("MainContent"), ContentPlaceHolder)*'Null Reference Exception here*
If Not mpContentPlaceHolder Is Nothing Then
mpLabel = CType(mpContentPlaceHolder.FindControl("lblPageIdentifier"), Label)
If Not mpLabel Is Nothing Then
mpLabel.Text = pageId
End If
End If
End Sub
when I call this function from another class in page load like this it throws null ref ex:
Dim oWebForm1 As WebForm1 = New WebForm1()
oWebForm1.PageIdentity("SomeText")
I must be doing something wrong in creating the instance? I tryed writing it as a Public Shared Function first but that created other problems. Can anyone help?
UPDATE: #Joey I replaced the commented line of code below as you suggested and put the sub in the master page code behind, Site1.Master.vb:
'mpContentPlaceHolder = CType(Master.FindControl("MainContent"), ContentPlaceHolder)
mpContentPlaceHolder = CType(Me.FindControl("MainContent"), ContentPlaceHolder)
I also ensured that the page directive on other pages included:
<%# MasterType VirtualPath = "~/Site1.Master" %>
On a test page, I called the sub like so:
Dim _SiteMaster As MasterPage = TryCast(Me.Master, MasterPage)
_SiteMaster.PageIdentity("SomeText")
I am getting blue squiggly line error, message: "PageIdentity is not a member of System.Web.UI.MasterPage"
The Master page inherits like this:
Public Partial Class Site1
Inherits System.Web.UI.MasterPage
The page calling the sub inherits like this
Public Class WebForm1
Inherits System.Web.UI.Page
Since you require the PageIdentity subroutine to be somewhat global you can move it into your master page. The master page can then be called by any page that references it. Use the following code on any page to call the PageIdentity routine:
Dim _SiteMaster As Site1 = TryCast(Me.Master, Site1)
_SiteMaster.PageIdentity("SomeText")

Invoking Method of Presenter on Activation

I'm using Smart Client Software Factory 2008. In the module controller, I have code that creates a new child controller only if it hasn't been created, by doing something like the following:
Dim key = "Item-" + item.ID.ToString()
Dim childWorkItem = Me.WorkItem.WorkItems.Get(Of ControlledWorkItem(Of ItemWorkItemController))(key)
If childWorkItem Is Nothing Then
childWorkItem = Me.WorkItem.WorkItems.AddNew(Of ControlledWorkItem(Of ItemWorkItemController))(key)
Else
childWorkItem.Activate()
End If
Multiple items reuse the same key, so when that action is triggered, it shows the tab instead of creating a new instance of it. This works great.
However, there is one drawback. Once activated, I need to run a check within that item's presenter. So I need to call a method on the presenter. Is there a way to invoka a method on the presenter, or is there an event that runs on the view when the work item is activated? I'm not sure how to make that happen?
Thanks.
If you are using a Smart Part as your View you should be able to accomplish this using the IWorkspace.SmartPartActivated event.
This is how I have it setup in my project. I apologize, my code is all in C# but you should be able to apply it in VB relatively easily.
The WorkItemController class has the Activate method setup like this
ISmartPartView _smartPartView
public void Activate()
{
IWorkspace contentWorkspace = this.WorkItem.Workspaces[WorkspaceNames.ShellContentWorkspace];
contentWorkspace.Activate(_smartPartView);
WorkItem.Activate();
}
In the ISmartPartView Presenter class you should be able to create a handler for the SmartPartActivated event like this:
IWorkspace contentWorkspace = this.WorkItem.Workspaces[WorkspaceNames.ShellContentWorkspace];
contentWorkspace.SmartPartActivated += workSpaceSmartPart_ActivatedHandler;
In the workSpaceSmartPart_ActivatedHandler event handler, you can check the SmartPart being activated and if its your ISmartPartView class you can run the desired code.

NullReferenceException on dll

Here is my code I get the error on:
Imports ADFactory
Public Class Salary
Inherits Salary_Datalayer
Protected _AD As New ADFactory.ADFactory
Protected Sub Page_Load(...)Handles Me.Load
_user = "username"
sDealer = _AD.GetUserCompany(_user)
It states that Protected _AD As New ADFactory.ADFactory is the line throwing the exception. I've looked online and read and changed it several times, declared 'New', am I missing something simple?
PatFromCanada was correct, my ADFactory was the problem. I didn't properly initialize a connection string within the reference, thus always throwing a nullexception, which apparently, I run into quite often in my questions. Thanks PatFromCanada!

Context issue in IHttpHandler

Sorry, this can be a basic question for advanced VB.NET programmers but I am a beginner in VB.NET so I need your advice.
I have a web application and the login is required for some specific pages. To check if the user is logged in, the old programmer used this technique:
Dim sv As New WL.SessionVariables(Me.Context)
If Not (sv.IsLoggedIn) Then
Response.Redirect(WL.SiteMap.GetLoginURL())
End If
Well, I have to use this Logged In checking in a handler done by me and I tried this:
Public Class CustomHandler
Implements System.Web.IHttpHandler, IReadOnlySessionState
Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
Dim sv As New WL.SessionVariables(context)
If Not (sv.IsLoggedIn) Then
context.Response.Write("No access unless you're the CEO!!!" & sv.IsLoggedIn)
ElseIf sv.IsLoggedIn Then
DownloadFile(context)
Else
End If
End Sub
//other code
End Class
Well, the "is logged in" checking is always false (even after I login) and I think it's an issue with the context. So all the other pages works fine with logging checking but this handler have this specific issue.
Can you guys give a helping hand?
UPDATE:
The logged in is done trough this method:
Public Sub SetCreditialCookie(ByVal accountID As Integer)
Me.AccountID = accountID
m_context.Session.Item("loggedInAccount") = accountID
m_context.Response.Cookies.Add(New System.Web.HttpCookie("account_id", CStr(m_context.Session.Item("account_id"))))
m_context.Response.Cookies("account_id").Expires = DateTime.Now.AddDays(5)
End Sub
and to check it it's logged in, this method is called:
Public Function IsLoggedIn() As Boolean
If Not m_context.Session.Item("loggedInAccount") Is Nothing And Me.AccountID = m_context.Session.Item("loggedInAccount") Then
Return True
Else
Return False
End If
End Function
UPDATE 2:
- debugging the code shown that there were multiple kind of logins and I was checking the wrong one with the session.
Due to the use of IReadOnlySessionState, is it possible that the SessionVariables class attempts in some way to modify the Session, which in turn causes an error (possibly handled and not visible to you).
If this is the case it could mean that the IsLoggedIn property is not correctly initialised, or does not function as expected?
Do you have access to the code for the class. If so, try debugging it to see what is happening.