# .NET and More > WPF, WCF, WF >  [RESOLVED] Call a function in one form from another

## trevorjeaton

Hi everyone,

I'm still a noob at WPF and i'm trying to stop thinking in WinForms mode....I have a function in a WPF app on a form called 'loginform2'.  The function is as follows in loginform2.xaml.vb:



```

Public Function showlogin() As String
        showlogin = Trim(firstname.ToUpper) + " " + Trim(lastname.ToUpper)
End Function
```

i would like to get the value of showlogin() by calling it from my main form, in this case, mainwindow.xaml.vb

In winforms fashion (using wpf syntax for the label) if i were to plug the value into a label i would simply call the following from mainwindow:



```

label1.content = loginform2.showlogin
```


if it were winforms the code would be:



```

label1.text = loginform2.showlogin
```

but intellisense is not showing the showlogin function and when i override it and type it in anyway I get "Reference to a non-shared member requires an object reference".

Any help would be appreciated

Thanks again everyone.

----------


## Lightning

The loginform2 doesn't exist in mainwindow.xaml.vb. The fact the it is in vb.Net is a "stupid/ugly" thing in vb.Net-Forms. You should create a seperate class with properties like FirstName, LastName, .... And a methode called GetLogin (showlogin is wrong, it doesn't show anything).

----------


## trevorjeaton

the showlogin was only for example - basically what i have is a sql database on the back end, and if the username and password are a match in my "loginform", loginform has several public functions in it (firstname, lastname, is_administrator etc) that i store for use throughout the remainder of the program and call on them as needed via loginform2.firstname, loginform2.lastname, loginform2.isadministrator etc etc

And again, forgive me because my head is still thinking in windows forms types of processes, but you're saying i should create a class that hits the database, store alll of the functions in that class, then call those functions from the class if the user authenticates correctly?

----------


## Lightning

That is correct

----------


## trevorjeaton

hmmmm - so far i'm unsuccessful - here's what i did for a test:

i right clicked my project and selected add, then class.
i called it logindetailsclass

for the test i added the following to the code:



```

public test as string = "test"
```

i added a label called label22 to my mainwindow.xaml

in the window_loaded event i added (or rather tried to add):



```

label22.content = logindetailsclass.test
```

no joy - its not even in the intellisense.  HOWEVER, if i go the my.windows.loginform2 route, the intellisense shows up with the public functions mentioned in the original loginform2, but errors out with:



```

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'ElementName=txtusername'. BindingExpression:(no path); DataItem=null; target element is 'loginform2' (Name=''); target property is 'FocusedElement' (type 'IInputElement')
```

the details of that error referencing "txtusername", is where the textbox on loginform2 that the user types in their username obviously

what am i missing?  This VB 2010 and WPF with .net4 in case that needs to be clarified as well......

gotta love learning new things - any suggestions on what (probably) simple thing i'm missing?

----------


## trevorjeaton

okay i think i got it - my thanks to Olaf Rabbachin in this forum here and to Lightning above for the assistance up to this point:

http://social.msdn.microsoft.com/For...4-ac1905ddfbae

that states the following (in case the URL expires or the post gets deleted on that forum :Smilie: 

"let's assume your Public Shared Sub was called DoSomething and the window containing that Sub is called MyWindow . I suppose what you're really doing is that you are simply calling MyWindow.DoSomething() somewhere in your code. However, MyWindow in this case is not a reference to the window but rather the name of the window-class . That being said, I presume that what you're trying to achieve is to call a method in your MyWindow when it has actually been loaded (displayed).
It actually wouldn't make any sense otherwise - an instance of any windows always has to be created before you can work with it. That being said, the fact that your method is Shared doesn't make any sense in this case as it will always refer to an instance of its class (i.e. MyWindow ) that it is part of. Thus, here's the sample method for MyWindow :"



```
   Public Sub DoSomething()
      MessageBox.Show("Alright, this works.")
   End Sub
```

Now, when you want to call the method from another window (say TheCallingWindow ), you'll thus have to retrieve/use a reference to MyWindow. That is, you can't just call MyWindow.DoSomething() . Instead, your code in TheCallingWindow needs to "find" (a reference to) that window first. In order to retrieve a list of all windows that have been instantiated, you can call Application.Current.Windows which will return a WindowCollection. Since you're then looking for a window with a specific name, you can either loop through the collection (item.GetType.Name will give you the name of each item in the collection) or use a little LINQ to do the same thing. Assuming that you're a good guy and have Option Strict On , you'll finally have to cast the item into your window class and may then call its method:



```
   Dim strWindowToLookFor As String = GetType(MyWindow).Name
   Dim win = ( _
         From w In Application.Current.Windows _
         Where DirectCast(w, Window).GetType.Name = strWindowToLookFor _
         Select w _
      ).FirstOrDefault
   If win IsNot Nothing Then
      DirectCast(win, MyWindow).DoSomething()
   End If
```

Some other interesting info is also that when i called my form in my winforms app, i was calling it from loginform2 by dim'ing a new instance of form1 then calling me.close() on the pretence that the thread would close loginform2 after form1 was closed - WPF closes it right away, hence no functions available

----------


## trevorjeaton

Last but not least, here's my actual test code in the case of loginform2 and calling a public function called "isadmin" (a database boolean that is T or F if the user is classified as an administrator i could have used the showlogin function in the posts above as well) - it's a label for this example but in reality i would run if-then-else checks that will determine the functionality of controls on my main form.



```

Dim strwindowtolookfor As String = GetType(loginform2).Name

Dim win = (From w In Application.Current.Windows _
Where (DirectCast(w, Window).GetType.Name = strwindowtolookfor) _
Select w).FirstOrDefault

If win IsNot Nothing Then
    Label22.Content = DirectCast(win, loginform2).isadmin()
End If
```

The other thing that i discovered is that if i put that code into the window_loaded event, it wouldn't fire or even update the label, but if i added it to a button, that it would work - with some digging, this needed to be fired in the window_activated event, not window_loaded.

Last but not least, this is a linq example and is a few lines of code to grab a single value - i have roughly 20-30 public functions that the entire app needs access to, so if anybody has a more efficient way, i'm all ears - for now, this will do though - just lots of cutting and pasting.

----------


## trevorjeaton

here's one more plug for Olaf that shows a few other neat tricks:

http://www.blogs.intuidev.com/post/2...owHelpers.aspx

----------

