How to get all forms in a windows form application - winforms

I have a windows form application.
I want to get all of form that application has, but i just found about the function Application.OpenForms.
This function return all of forms are opening.
But I want to get all of forms in that application.
Is there any functions to get but not add to FormsColection for new Form created like this solution https://support.microsoft.com/en-us/kb/815707 ?
Thank you!

"All of the forms that an application has" typically would mean using reflection for all of the types in the assembly that inherit from the Windows.Forms.Form class.
The Application.OpenForms only tracks forms that are opened, not necessarily those that have been instantiated and not opened.
What you really need to do is track all of the forms when the form objects are instantiated. See code below:
Public Class Form1
Public Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Globals.InstantiatedForms.Add(Me)
End Sub
End Class
Public Module Globals
Public InstantiatedForms As New List(Of Windows.Forms.Form)
End Module

Related

WPF Custom Control VB.net

I've created a custom control called ecTextBox in VB.NET which uses a control template in Generic.xaml. That works.
In code behind of the custom control I override metadata in the constructor:
Public Sub New()
DefaultStyleKeyProperty.OverrideMetadata(GetType(ecTextBox), New FrameworkPropertyMetadata(GetType(ecTextBox)))
End Sub
In MainWindow.xaml I use the custom control with a simple
<ec:ecTextBox/>
That works fine.
But if I throw a second control or change the propertys of the first ecTextBox in MainWindow.xaml, I get the message "PropertyMetaData is already registered for type ecTextBox".
In StackOverflow I've read, that C# programmers should use the static-Keyword for the constructor. But if I change the constructor to
Shared Sub New
DefaultStyleKeyProperty.OverrideMetadata(GetType(ecTextBox), New FrameworkPropertyMetadata(GetType(ecTextBox)))
End Sub
the second custom control don't uses the control template but appears as a normal TextBox without Border.
What is the correct way to override the metadata for all used ecTextBox controls and prevent the errors?
This is the solution:
Public Sub New()
MyBase.New()
End Sub
Shared Sub New()
DefaultStyleKeyProperty.OverrideMetadata(GetType(ecTextBox), New FrameworkPropertyMetadata(GetType(ecTextBox)))
End Sub

Access windows forms function from WPF windw

i am trying to call a function in Form1 from WPF window and i am getting the following error
"Reference to a non-shared member requires an object reference."
also getting the same error when trying to access the Public variables in Form1 from wpf window.
is it not possiable to do it?
So according to the MSDN this error, this is a problem with trying to reference instance variables as if they are static.
If your class is Form1, you cannot access methods or variables that are not static by calling Form1.Method(). This won't work ever, not just in WPF. This is pretty basic stuff, you might want to read up more on VB. Check out Shared and Static documentation.
To access, for example, the method Show() on Form1, you must instantiate (create an instance of an object), and call the method on your object. Like this.
Dim frm As New Form1()
frm.Show()

Best way to get generated ADO.Net DbContext into View-Models

I’m currently working on a WPF MVVM application using MVVM Light as the MVVM Framework, Entity Framework as the ORM, and MS Synch Framework as the means of synchronizing a Local Sql Compact DB with an online SQL database. The application is also fairly complex in scope, as it is meant to manage an asset, calculating wear and tear on the use of that asset through its lifetime. Thankfully I’m new to all these technologies so ignorance is bliss :) I’ve found lots of tutorials and information on creating the Unit of Work Patter and Repository pattern. However, I’m using the new DbContext, which I’ve read already uses these two patterns.
My current issue relates to using the new DbContext in Entity Framework. I’ve used DbContext Generator template in VS, and so I have a MyDbModelContainer. I’ve used this directly from my view models, which creates a Context per VM, which I’m pretty sure is a bad idea. Here is my constructor for a Parent/Child type data entry scenario, I construct the container here, and them use MVVM Light to message over a selected item to the child VM.
Private FatigueDbContext As FatigueModelContainer
Public Sub New()
If IsInDesignMode = False Then
FatigueDbContext = New FatigueModelContainer
FatigueDbContext.CtMaterials.Load()
CtMaterialsCollection = FatigueDbContext.CtMaterials.Local
FatigueDbContext.CtManufactures.Load()
CtManufactures = FatigueDbContext.CtManufactures.Local
End If
End Sub
I want to keep the Context open for the lifetime of my View-Model so that I can use MyDbModelContainer.MyTable.Local for bindings. So while this is working, how should I handle this correctly?
My gut feeling is I need to somehow wrap the auto-generated MyDbModelContainer into some classes that basically only contain the tables and functions that I need to work with on that View-Model.
I’m not using a View-Model Locator, but rather another View-Model to manage my views, got the idea from Rachel's blog , and I like the concept. However, it means that I’m creating all my View-Models up front, and initializing any of the view model dependencies up front. I only have one window, and am just switching between View-Models they stay in memory and I don’t have any way to close my DbContext when switching to a new View-Model.
Here is the code for the Shell View-Model
Public Class ShellViewModel
Inherits ViewModelBase
#Region "Fields"
Private _changePageCommand As ICommand
Private _currentPageViewModel As IPageViewModel
Private _pageViewModels As List(Of IPageViewModel)
#End Region
Public Sub New()
Dim DialogService As New ModalDialogService
' Add available pages
PageViewModels.Add(New ImportJobDataViewModel(DialogService))
PageViewModels.Add(New TestViewModel())
PageViewModels.Add(New ReverseBendUtilityViewModel(DialogService))
' Set starting page
CurrentPageViewModel = PageViewModels(0)
End Sub
#Region "Properties / Commands"
Public ReadOnly Property ChangePageCommand() As ICommand
Get
If _changePageCommand Is Nothing Then
_changePageCommand = New RelayCommand(Of IPageViewModel)(Sub(param) ChangeViewModel(param))
End If
Return _changePageCommand
End Get
End Property
Private Function IsViewPageModel(viewPageModel As IPageViewModel) As Boolean
If TypeOf (viewPageModel) Is IPageViewModel Then
Return True
Else
Return False
End If
End Function
Public ReadOnly Property PageViewModels() As List(Of IPageViewModel)
Get
If _pageViewModels Is Nothing Then
_pageViewModels = New List(Of IPageViewModel)()
End If
Return _pageViewModels
End Get
End Property
Public Property CurrentPageViewModel() As IPageViewModel
Get
Return _currentPageViewModel
End Get
Set(value As IPageViewModel)
If _currentPageViewModel IsNot value Then
_currentPageViewModel = value
RaisePropertyChanged(Function() CurrentPageViewModel)
End If
End Set
End Property
#End Region
#Region "Methods"
Private Sub ChangeViewModel(viewModel As IPageViewModel)
If Not PageViewModels.Contains(viewModel) Then
PageViewModels.Add(viewModel)
End If
CurrentPageViewModel = PageViewModels.FirstOrDefault(Function(vm) vm Is viewModel)
End Sub
#End Region
End Class
So to sum it all up... Should I be creating some separate class aside from the auto-generated FatigueModelContainer, what would that class look like, would it be just one more class, or would it be separate classes based on the business operations. Such as a class to Add, Update and Delete Manufactures, a class to Add, Update and Delete Materials, etc. Where should I be inserting it into the VM? Presumably in the Shell-View-Model?
You can solve this problem without really touching your db context. The idea is that even if the VM stays in memory, you only need the model instance to be initialized when the VM's view is active.
There is a nice way of going about this in Caliburn.Micro: Screens and Conductors, but it's really not specific to the mvvm framework.
In the most basic case, as Rachel mentioned in the comment above, you extend your IPageViewModel to include functions which handle activation- and deactivation-logic for the VM: activation logic is called when the VM is activated, deactivation logic is called when the VM is deactivated.
The actual call to activate/deactivate would be made in the container for the IPageViewModels, for instance:
Public Property CurrentPageViewModel() As IPageViewModel
Get
Return _currentPageViewModel
End Get
Set(value As IPageViewModel)
If _currentPageViewModel Is value Then
Return
End If
If _currentPageViewModel IsNot Nothing Then
_currentPageViewModel.Deactivate()
End If
_currentPageViewModel = value
If value IsNot Nothing Then
value.Activate()
End If
RaisePropertyChanged(Function() CurrentPageViewModel)
End Set
End Property
That way you can close the db connection/detach the DbContext when a page is deactivated and open it when the page is activated.

Multiple Instances of the same WPF Window and ViewModel

I have a window named 'winAppt.xaml' and a view model called 'ItemViewModel.vb'. I would like the user to be able to open multiple instances of the 'winAppt.xaml' window to show different accounts on the screen at once. Problem right now is that when the second instance of 'winAppt.xaml' loads the first instance has some of it's data replaced with the second instance.
I'm currently doing something like this
Dim i As New ItemViewModel()
i.Load(itemID)
Dim fDetailRec As New winAppt(i)
fDetailRec.ShowDialog()
I then set the DataContext of my window to the view model passed in.
Public Sub New(ByVal i As ItemViewModel)
Me.DataContext = i
End Sub
Found a shared reference to a class inside the view model. This class was declared in a module and persisted throughout the application. This class contained a list that I thought I was passing to my ViewModel, it was really referencing it.

WPF and VB.net: Data Binding to Separate Class created outside of Expression Blend

I have a WPF application with form that has a textbox named "txtStatusWindow". I also have a vb.net class handed to me by a co-worker that needs to be called and executed by the code in my application code-behind. My co-worker insists that I will need to use common .net events to update the textbox on my form.
The separate vb.net class:
Public Class globalclass
Public Event txtStatusWindow(ByVal Text As String)
Public Sub InitializeProgram()
RaiseEvent txtStatusWindow("Updating something.")
System.Threading.Thread.Sleep(2000)
RaiseEvent txtStatusWindow("Updating something else.")
System.Threading.Thread.Sleep(2000)
RaiseEvent txtStatusWindow("Updating something other than else.")
System.Threading.Thread.Sleep(2000)
RaiseEvent txtStatusWindow("Updating something other than the else stuff.")
System.Threading.Thread.Sleep(2000)
End Sub
End Class
I need to be able to call the sub "InitializeProgram()" from my code-behind, and it needs to be able to update "txtStatusWindow.text" as it runs.
I told him that the updating of the text box can be done with data-binding, but I don't know how to integrate a separate class like this into my project, how to call methods in it, or how to cause it to update my text blocks through data binding.
I also suggested that the methods in this class aren't optimal for connecting to the WPF project anyway, but he just wrote it as an example to discover how to connect the two projects.
Eventually, I will need to integrate classes like these that will be running separate threads to update their data from a dynamic source, and cause many controls to update in my application.
So far, the only way we have been able to get this to work from my code-behind is this:
Partial Public Class SplashScreen
Dim NewText as String
Public WithEvents Globals As globalclass = New globalclass
Public Delegate Sub StringDelegate(ByVal Text As String)
Public SplashText As String
Public Sub New()
MyBase.New()
Me.InitializeComponent()
Me.Show()
Globals.InitializeProgram()
End Sub
Public Sub UpdateSplashscreenHandler(ByVal Text As String) Handles Globals.UpdateSplashScreen
StatusWindowText.Text = Text
End Sub
Notwithstanding the fact that the WPF screen "freezes" until the "globalclass InitializeProgram" method completes (txtStatusWindow.Text does not update while sub without using the esoteric "refresh" extension...), I fully believe we are going about this the wrong way.
There are precious few examples out there concerning the integration and then binding to objects in existing code. Thanks for examining our little quandary.
If this status window is in XAML and the status window is a UserControl, then add a StatusText dependency property to the status window. Then, in the XAML you can bind to the value of that property with something like:
<UserControl x:Name="MyStatusWindow" ...>
<TextBlock Text="{Binding Path=StatusText, ElementName=MyStatusWindow}" />
</UserControl>
Then, from your event, just update the value of that StatusText property.
(Is that even close to what you were asking?)
Also, about that freezing: Instead of doing that updating in the constructor of that class, you might want to do it from the Loaded event of that control. It will still be freezing, though, unless you move it to a separate thread. Right now, that's happening on the same thread that the UI message pump is running on. This is the Dispatcher for that UI.

Resources