WPF Running a command on a windows form - wpf

I have a WPF Project to which i've added a Windows Form.
The windows form has a method runme(). But I'd like to call it from the WPF form.
Currently I've used
Dim wpfForm as new wpfForm
wpfForm.Show()
to display the the WPF form from a Windows form.
I'm not sure how to send a command back though.
I've tried:
Me.parent.runme()
But this gives me errors

The only way that I can think of to do what you are wanting is to create a Custom Constructor for your Winform and pass the reference to the Wpf Window to it. There appears to be no easy way to assign a WPF Window as an Owner/Parent of a Winforms Window.
Winforms Form
Public Class Form1
Dim myParent As System.Windows.Window
Public Sub New()
InitializeComponent()
End Sub
Public Sub New(parent As System.Windows.Window)
myParent = parent
InitializeComponent()
End Sub
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
CType(myParent, MainWindow).runMe()
End Sub
End Class
Wpf Form
Class MainWindow
Dim winForm As Form1
Private Sub Button1_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button1.Click
winForm = New Form1(Me)
winForm.Show()
End Sub
Public Sub runMe()
Me.Background = Brushes.Red
End Sub
End Class

Eventually what worked was to create an interface as suggested by Cyborgx37
Interface ILogOut
Sub DoIt()
End Interface
Class WinFormWindow : Implements ILogOut
Public Sub DoIt() Implements ILogOut.DoIt
MsgBox("Message Received!")
End Sub
End Class
You can then use the ILogOut interface to send a message to the Windows forms window from a WPF window

Related

WPF form to form update

I am trying to update a label from one form to another. the code is compiling fine but not updating?
Class MainWindow
Private Sub Window_Loaded(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
Dim frm As New Window1
frm.Show()
End Sub
End Class
second form:
Public Class Window1
Private Sub Button1_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button1.Click
My.Windows.MainWindow.Label1.Content = "dsfdsfsdf"
My.Windows.MainWindow.Label1.UpdateLayout()
End Sub
End Class
it doesn't update the main form's label... hope that makes it clearer
So here's the code that you actually need:
Public Class Window1
Private Sub Button1_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button1.Click
DirectCast(Application.Current.MainWindow, MainWindow).Label1.Content = "test"
End Sub
End Class
I'm not sure what the My.Windows collection is, but the Application.MainWindow gives you a reference to the window that is set as the start up object in the project properties (or the one you set in your app.xaml.cs file). Previously you were probably getting a reference to a different instance of the Window1 class, hence it was running and not throwing an exceptions, but since it wasn't the actual visible instance of the window then you didn't see any changes.

Changing host WinForm properties from ViewModel bound to ElementHost

Can anyone suggest approaches that will allow me to change the properties of a host WinForm from a WPF element in an ElementHost?
I have an MVVM application using Prism that's bound to an ElementHost. I would like to change the WinForm title, resize the WinForm and close the WinForm from within my ViewModel.
I understand receiving data from a WPF composite control described in this article but I can't see how that will work in a ViewModel.
App is the WinForm
ChartWizardViewModel is the ViewModel I want to change the properties of App from.
Everything else is the Prism architecture. Shell, Bootstrapper etc.
Public Class App
Public Sub New(ByVal modulesToLoad As List(Of String))
' This call is required by the designer.
InitializeComponent()
If Application.Current Is Nothing Then
Dim wpfAppAdapter As New WpfApplicationAdapter
End If
' Load the application modules
Dim formBootstrapper As New Bootstrapper(modulesToLoad)
formBootstrapper.Run()
' Get the current instance of shell and bind it to the ElementHost
Dim shellElement = formBootstrapper.Container.Resolve(Of Shell)()
ehMaster.Child = shellElement
End Sub
End Class
Public NotInheritable Class Bootstrapper
Inherits UnityBootstrapper
Private _modulesToLoad As List(Of String) ' The modules that we want to load
Public Sub New(ByVal modulesToLoad As List(Of String))
_modulesToLoad = modulesToLoad
End Sub
Protected Overrides Function CreateShell() As DependencyObject
Dim shell = Container.Resolve(Of Shell)()
Return shell
End Function
Protected Overrides Function GetModuleCatalog() As IModuleCatalog
Dim catalog As ModuleCatalog = New ConfigurationModuleCatalog()
For Each moduleToLoad As String In _modulesToLoad
Select Case StringHelper.CleanString(moduleToLoad)
Case "chartwizardmodule"
catalog.AddModule(GetType(ChartWizardModule))
End Select
Next
Return catalog
End Function
End Class
Public NotInheritable Class ChartWizardModule
Implements IModule
Private ReadOnly regionManager As IRegionManager
Public Sub Initialize() Implements IModule.Initialize
regionManager.RegisterViewWithRegion("MainRegion", GetType(MainWindow))
End Sub
Public Sub New(regionManager As IRegionManager)
Me.regionManager = regionManager
End Sub
End Class
Partial Public Class MainWindow
Private _objChartWizardViewModel As ChartWizardViewModel ' The chart wizard base view model that controls the rest of the views
Private Sub MainWindow_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
Dim objChartWizardViewModel As New ChartWizardViewModel()
_objChartWizardViewModel = objChartWizardViewModel
' Data Context for the Chart Wizard
Me.DataContext = _objChartWizardViewModel
End Sub
End Class
Public Class ChartWizardViewModel
Implements INotifyPropertyChanged
' I need to change the properties of the WinForm (App) from here
End Class
I solved this with an EventAggregator as discussed in this post
Using EventAggregator to communicate between WPF in ElementHost and host WinForm

Cannot update a treeview inside a usercontrol

I created a usercontrol with a treeview inside it. The treeview will be populated if I add nodes in the onload handler of the usercontrol. But after that(for example, I click a button in its parent form), the treeview will not refresh. I can see the nodes was updated in memory, but it just cannot display on the screen. I called refresh/update after adding nodes. Any suggestion is appreciated.
I put a quick test together based on your description and it seems to paint just fine.
UserControl1
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class UserControl1
Inherits System.Windows.Forms.UserControl
'UserControl 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 Windows Form Designer
Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
Me.TreeView1 = New System.Windows.Forms.TreeView
Me.SuspendLayout()
'
'TreeView1
'
Me.TreeView1.Dock = System.Windows.Forms.DockStyle.Fill
Me.TreeView1.Location = New System.Drawing.Point(0, 0)
Me.TreeView1.Name = "TreeView1"
Me.TreeView1.Size = New System.Drawing.Size(150, 150)
Me.TreeView1.TabIndex = 0
'
'UserControl1
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.Controls.Add(Me.TreeView1)
Me.Name = "UserControl1"
Me.ResumeLayout(False)
End Sub
Friend WithEvents TreeView1 As System.Windows.Forms.TreeView
End Class
Public Class UserControl1
Public Sub AddNewNode(ByVal text As System.String)
TreeView1.Nodes.Add(text)
End Sub
End Class
Put the usercontrol on a form with a button
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
UserControl11.AddNewNode(Now.ToString)
End Sub
End Class
If you are seeing proper painting as well then look at any graphics handling in the parent form then the usercontrol then the controls within the usercontrol. We really need more info.
Thank you, Dave. I figured it out. I put the usercontrol twice to my form by mistake(I cannot remember how I did it). And the one I operate is underneath the other one. That's why I cannot see it. Sorry for wasting your time.

How to call a Public Sub function of a window from another Window

I have A Wpf window with a Public Sub function(Window1). I need to execute that function from another window. Something like this:
Private Sub Window2_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Window1.Loaded
Dim Window1 As New Window 1
Window1.function()
End Sub
I'm very new to wpf. Please help me on this.
Thanks In Advance.
Make the function public in Window1.
Class Window1
Public Sub MyPublicFunction()
'DoSomething'
End Sub
End Class
Any specific reason why it has to be in Windows1 and be an instance function? You could do this as a static public function in the App class so every part of your project gets access to it.

How can I make a globally accessible datatable in a Winforms application?

Disclaimer: I am new to Winforms.
I need to declare a datatable that I can load with data when the main form loads. I then want to be able to reference the datatable from within events like when a button is clicked etc.
Where/how should I declare this?
I'd suggest a private member at the top of the form class meaning it will be accessible throughout the entire form. No need for a public property, unless you have to access it outside of the form but its best to default to private if you are unsure.
Update: If it is a simple one form app, please check the suggestion by Quarrelsome..
Just Declare as a public property of your Data Access class.
Public
Class Form3
Private myTable as New DataTable
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
MsgBox(t.Rows.Count)
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
MsgBox(t.Rows.Count)
End Sub
End Class

Resources