Imports System.Collections.ObjectModel Imports System.Threading Imports System.Windows.Threading Imports System.Runtime.InteropServices Imports System.Math Imports EgtUILib Imports EgtWPFLib5 Public Class MainWindowVM Inherits ViewModelBase #Region "FIELDS" ' EGALTECH ENVIRONMENT FIELDS Private m_objMutex As Mutex Private m_sDataRoot As String = String.Empty Private m_sConfigDir As String = String.Empty Private m_OnTerminateProcessCallback As New OnTerminateProcessCallback(AddressOf OnTerminateProcess) ' EGALTECH ENVIRONMENT FIELDS WITH PROPERTY Private m_nDebug As Integer = 0 Public ReadOnly Property DebugLevel As Integer Get Return m_nDebug End Get End Property Private m_sVersion As String = "1.1a1" Public ReadOnly Property Version As String Get Return m_sVersion End Get End Property Private m_Title As String = String.Empty Public Property Title As String Get Return m_Title End Get Set(value As String) If value <> m_Title Then m_Title = value OnPropertyChanged("Title") End If End Set End Property Private m_cmdMainWindow_ContentRendered As ICommand Private m_cmdAboutBox As ICommand ' MainWindow Activated Event Private m_cmdMainWindow_Activated As ICommand ' MainWindow Deactivated Event Private m_cmdMainWindow_Deactivated As ICommand ' MainWindow Closing Event Private m_cmdMainWindow_Closing As ICommand Private m_cmdCloseApplication As ICommand ' GRAPHICAL ELEMENTS Private m_TopCommandBar As TopCommandBarV Public ReadOnly Property TopCommandBar As TopCommandBarV Get If IsNothing(m_TopCommandBar) Then m_TopCommandBar = New TopCommandBarV m_TopCommandBar.DataContext = New TopCommandBarVM End If Return m_TopCommandBar End Get End Property ' GRAPHICAL FIELDS WITH PROPERTY Private m_StatusBar As StatusBarV Private m_bfirst As Boolean = True Public ReadOnly Property StatusBar As StatusBarV Get If m_bfirst Then m_bfirst = False m_StatusBar = New StatusBarV m_StatusBar.DataContext = New MyStatusBarVM End If Return m_StatusBar End Get End Property Private m_ProjectPage As ProjectV Private m_bFirstProjectPage As Boolean = True Public ReadOnly Property ProjectPage As ProjectV Get If m_bFirstProjectPage Then m_bFirstProjectPage = False m_ProjectPage = New ProjectV m_ProjectPage.DataContext = New ProjectVM End If Return m_ProjectPage End Get End Property Public ReadOnly Property IconSource As String Get #If PLATFORM = "x64" Then Return "/Resources/EgtCAM5_64.ico" #else Return "/Resources/EgtCAM5.ico" #End If End Get End Property #End Region #Region "CONSTRUCTOR" Sub New() ' Inizializzo EgtCAM5Map Map.BeginInit(Me) ' INITIALIZE EGALTECH ENVIRONMENT InitializeEgtEnvironment() AddHandler Application.Current.MainWindow.KeyDown, AddressOf MainWindow_KeyDown End Sub #End Region ' Constructor #Region "COMMANDS" #Region "AboutBoxCommand" ' Returns a command that manage the MainWindow_Unloaded command Public ReadOnly Property AboutBoxCommand() As ICommand Get If m_cmdAboutBox Is Nothing Then m_cmdAboutBox = New Command(AddressOf AboutBox) End If Return m_cmdAboutBox End Get End Property ' Manage the MainWindow_Unloaded event. This method is invoked by the cmdMainWindow_Unloaded. Public Sub AboutBox(ByVal param As Object) Dim AboutBoxWindow As New AboutBoxWndV AboutBoxWindow.Owner = Application.Current.MainWindow AboutBoxWindow.ShowDialog() End Sub #End Region ' AboutBoxCommand #Region "CloseApplicationCommand" ''' ''' Returns a command that manage the MainWindow_Unloaded command ''' Public ReadOnly Property CloseApplicationCommand() As ICommand Get If m_cmdCloseApplication Is Nothing Then m_cmdCloseApplication = New RelayCommand(AddressOf CloseApplication) End If Return m_cmdCloseApplication End Get End Property ''' ''' Manage the MainWindow_Unloaded event. This method is invoked by the cmdMainWindow_Unloaded. ''' Public Sub CloseApplication(ByVal param As Object) If IniFile.m_bScriptRunning Then If Not IniFile.m_bFailedRun Then 'MessageBox.Show("Can't exit now. Wait until the end of the script execution", "", MessageBoxButton.OK, MessageBoxImage.Stop) Return End If End If If IniFile.m_bSimulExecuting Then ' Avvio l'arresto della simulazione refSimulationExpanderVM.SetSimulationStatus(MCH_SIM_ST.UI_STOP) IniFile.m_bSimulEndExitApp = True Return End If ' Gestisco eventuale file corrente modificato Map.refProjectVM.ManageModified() If m_allowWindowToClose Then Map.refMainWindowVM.ManageClosingApplication() ' Salvo posizione Form (se non minimizzato) If Application.Current.MainWindow.WindowState <> WindowState.Minimized Then Dim WinPos As New WinPos WindowToWinPos(Application.Current.MainWindow, WinPos) WritePrivateProfileWinPos(S_GENERAL, K_WINPLACE, WinPos.nFlag, WinPos.nLeft, WinPos.nTop, WinPos.nWidth, WinPos.nHeight) End If ' Terminazione generale di EgtInterface EgtExit() ' Salvo impostazione macchina corrente Map.refMachinePanelVM.SaveCurrentMachine() ' Aggiorno istanze usate m_objMutex.WaitOne(1000) Dim nTmp As Integer = GetPrivateProfileInt(S_GENERAL, K_INSTANCES, 0) nTmp -= (1 << (IniFile.m_nInstance - 1)) WritePrivateProfileString(S_GENERAL, K_INSTANCES, nTmp.ToString()) m_objMutex.ReleaseMutex() ' Rilascio mutex If Not IsNothing(m_objMutex) Then m_objMutex.Close() ' Chiudo la finestra principale del programma Application.Current.MainWindow.Close() Else IniFile.m_bSimulEndExitApp = False End If End Sub Private Function OnTerminateProcess( nExitCode As Integer) As Boolean ' Aggiorno istanze usate m_objMutex.WaitOne(1000) Dim nTmp As Integer = GetPrivateProfileInt(S_GENERAL, K_INSTANCES, 0) nTmp -= (1 << (IniFile.m_nInstance - 1)) WritePrivateProfileString(S_GENERAL, K_INSTANCES, nTmp.ToString()) m_objMutex.ReleaseMutex() ' Rilascio mutex If Not IsNothing(m_objMutex) Then m_objMutex.Close() ' Dichiaro di procedere con la terminazione del programma Return True End Function #End Region ' CloseApplicationCommand #Region "cmdMainWindow_ContentRendered" ''' ''' Returns a command that manage the MainWindow_ContentRendered command ''' Public ReadOnly Property cmdMainWindow_ContentRendered() As ICommand Get If m_cmdMainWindow_ContentRendered Is Nothing Then m_cmdMainWindow_ContentRendered = New RelayCommand(AddressOf MainWindow_ContentRendered) End If Return m_cmdMainWindow_ContentRendered End Get End Property ''' ''' Manage the MainWindow_ContentRendered event. This method is invoked by the cmdMainWindow_ContentRendered. ''' Public Sub MainWindow_ContentRendered(ByVal param As Object) ' Se errore di protezione, non posso proseguire If IniFile.m_nKeyLevel < 0 Then Return ' Notify the ContentRendered event NotifyMainWindow_ContentRendered() ' se sono in modalità solo cad If IniFile.m_ProjectMode = ProjectModeOpt.ONLYDRAW Then Map.refStatusBarVM.NotifyStatusOutput("Impossible finding Machines dir. EgtCAM5 will run in CAD-ONLY mode.") End If End Sub #End Region ' ContentRendered Command #Region "cmdMainWindow_Activated" ''' ''' Returns a command that manage the MainWindow_ContentRendered command ''' Public ReadOnly Property cmdMainWindow_Activated() As ICommand Get If m_cmdMainWindow_Activated Is Nothing Then m_cmdMainWindow_Activated = New RelayCommand(AddressOf MainWindow_Activated) End If Return m_cmdMainWindow_Activated End Get End Property ''' ''' Manage the MainWindow_ContentRendered event. This method is invoked by the cmdMainWindow_ContentRendered. ''' Public Sub MainWindow_Activated(ByVal param As Object) ' Notify the ContentRendered event End Sub #End Region ' Activated Command #Region "cmdMainWindow_Deactivated" ''' ''' Returns a command that manage the MainWindow_ContentRendered command ''' Public ReadOnly Property cmdMainWindow_Deactivated() As ICommand Get If m_cmdMainWindow_Deactivated Is Nothing Then m_cmdMainWindow_Deactivated = New RelayCommand(AddressOf MainWindow_Deactivated) End If Return m_cmdMainWindow_Deactivated End Get End Property ''' ''' Manage the MainWindow_ContentRendered event. This method is invoked by the cmdMainWindow_ContentRendered. ''' Public Sub MainWindow_Deactivated(ByVal param As Object) ' Notify the ContentRendered event End Sub #End Region ' Deactivated Command #End Region #Region "METHODS" #Region "RegisterMyMessages" Friend Sub CloseApplicationCmd() Map.refMainWindowVM.ManageClosingApplication() ' Terminazione generale di EgtInterface EgtExit() ' Rilascio mutex If Not IsNothing(m_objMutex) Then m_objMutex.Close() ' Aggiorno istanze usate Dim nTmp As Integer = GetPrivateProfileInt(S_GENERAL, K_INSTANCES, 0) nTmp -= (1 << (IniFile.m_nInstance - 1)) WritePrivateProfileString(S_GENERAL, K_INSTANCES, nTmp.ToString()) Application.Current.Shutdown() End Sub Friend Sub AllowWindowToClose(bBoolean As Boolean) m_allowWindowToClose = bBoolean End Sub Friend Sub UpdateMainWindowTitle(sString As String) Title = sString End Sub #End Region ''' ''' Method that initialize EgalTech environment ''' Private Sub InitializeEgtEnvironment() ' Title If Not IsNothing(Map.refProjectVM) Then Map.refProjectVM.EmitTitle() End If ' Impostazione path radice per i dati m_sDataRoot = System.AppDomain.CurrentDomain.BaseDirectory If EgtUILib.GetPrivateProfileString(S_DATA, K_DATAROOT, "", m_sDataRoot, m_sDataRoot & "\" & DAT_FILE_NAME) = 0 Then m_sDataRoot = System.AppDomain.CurrentDomain.BaseDirectory End If IniFile.m_sDataRoot = m_sDataRoot ' Impostazione direttorio di configurazione m_sConfigDir = m_sDataRoot & "\" & CONF_DIR IniFile.m_sConfigDir = m_sConfigDir ' Impostazione direttorio per file temporanei IniFile.m_sTempDir = m_sDataRoot & "\" & TEMP_DIR ' Impostazione path Ini file IniFile.m_sIniFile = m_sConfigDir & "\" & INI_FILE_NAME EgtWPFLib5.IniFile.m_sIniFile = m_sIniFile ' Impostazione path resources dir IniFile.m_sResourcesRoot = m_sDataRoot & "\" & RES_DIR ' Impostazione direttorio per le macchine If GetPrivateProfileString(S_MACH, K_MACHINESDIR, "", m_sMachinesRoot) = 0 Then m_sMachinesRoot = m_sDataRoot & "\" & MACHINES_DFL_DIR End If IniFile.m_sMachinesRoot = m_sMachinesRoot ' Impostazione direttorio toolmakers Dim sToolMakersDir As String = String.Empty GetPrivateProfileString(S_MACH, K_TOOLMAKERSDIR, "", sToolMakersDir) If Not String.IsNullOrWhiteSpace(sToolMakersDir) Then IniFile.m_sToolMakersDir = sToolMakersDir Else IniFile.m_sToolMakersDir = m_sDataRoot & "\" & TOOLMAKER_DFL_DIR End If ' Verifico indice di istanza ManageInstance() ' Imposto tipo di chiave EgtSetLockType(KEY_TYPE.HW) ' Leggo e imposto chiave di protezione ed eventuale chiave nesting Dim sLicFileName As String = "" GetPrivateProfileString(S_GENERAL, K_LICENCE, LIC_FILE_NAME, sLicFileName) Dim sLicFile As String = m_sConfigDir & "\" & sLicFileName Dim sKey As String = "" EgtUILib.GetPrivateProfileString(S_LICENCE, K_KEY, "", sKey, sLicFile) EgtSetKey(sKey) Dim sNestKey As String = "" EgtUILib.GetPrivateProfileString(S_LICENCE, K_NESTKEY, "", sNestKey, sLicFile) EgtSetNestKey(sNestKey) ' Impostazioni per chiave di rete Dim bNetKey As Boolean = (GetPrivateProfileInt(S_GENERAL, K_NETKEY, 0) = 1) EgtSetNetHwKey(bNetKey) Dim sLockId As String = "" EgtUILib.GetPrivateProfileString(S_LICENCE, K_LOCKID, "", sLockId, sLicFile) If Not String.IsNullOrEmpty(sLockId) Then EgtSetLockId(sLockId) End If ' Recupero livello e opzioni della chiave Dim bKey As Boolean = EgtGetKeyLevel(3279, 2605, 1, IniFile.m_nKeyLevel) And EgtGetKeyOptions(3279, 2605, 1, IniFile.m_nKeyOptions) ' Leggo e imposto livello utilizzatore IniFile.m_nUserLevel = Math.Min(IniFile.m_nKeyLevel, GetPrivateProfileInt(S_GENERAL, K_USERLEVEL, 1)) ' Imposto abilitazione lavorazioni avanzate MachineUtility.EnableAdvMachinings = IniFile.IsKeyEnabledAdvancedMachining() ' Inizializzazione generale di EgtInterface m_nDebug = GetPrivateProfileInt(S_GENERAL, K_DEBUG, 0) m_sVersion = My.Application.Info.Version.Major.ToString() & "." & My.Application.Info.Version.Minor.ToString() & (ChrW(97 - 1 + My.Application.Info.Version.Build)).ToString() & My.Application.Info.Version.Revision.ToString() IniFile.m_sLogFile = m_sTempDir & "\" & GENLOG_FILE_NAME.Replace("#", IniFile.m_nInstance.ToString()) Dim sLogMsg As String = "User " & Environment.MachineName & "\" & Environment.UserName & " Inst" & IniFile.m_nInstance.ToString() & " Ulv" & IniFile.m_nUserLevel.ToString() & " Dbg" & DebugLevel().ToString() & vbLf & My.Application.Info.Title.ToString() & " ver. " & m_sVersion EgtInit(m_nDebug, IniFile.m_sLogFile, sLogMsg) EgtSetOnTerminateProcess( m_OnTerminateProcessCallback) EgtSetUserLevel( IniFile.m_nUserLevel) ' Leggo direttorio dei messaggi (se manca uso direttorio di configurazione) Dim sMsgDir As String = String.Empty If GetPrivateProfileString(S_GENERAL, K_MESSAGESDIR, "", sMsgDir) = 0 Then sMsgDir = m_sConfigDir End If ' Inizializzo OptionModule OptionModule.InitOptionModule() ' Leggo file messaggi Dim sMsgFilePath As String = sMsgDir & "\" & OptionModule.m_SelectedLanguage.FilePath If Not EgtLoadMessages(sMsgFilePath) Then EgtOutLog("Error in EgtLoadMessages") End If ' Imposto dir font Nfe e font default Dim sNfeDir As String = String.Empty GetPrivateProfileString(S_GEOMDB, K_NFEFONTDIR, "", sNfeDir) GetPrivateProfileString(S_GEOMDB, K_DEFAULTFONT, "", OptionModule.m_sFontText) EgtSetFont(sNfeDir, OptionModule.m_sFontText) ' Imposto direttorio ausiliario per import/gestione BTL Dim sBtlAuxDir As String = String.Empty GetPrivateProfileString(S_IMPORT, K_BTLAUXDIR, "", sBtlAuxDir) EgtSetBtlAuxDir(sBtlAuxDir) ' Imposto direttorio libreria per export ThreeJs Dim sThreeJSLibDir As String = String.Empty GetPrivateProfileString(S_EXPORT, K_THREEJSLIBDIR, "", sThreeJSLibDir) EgtSetThreeJSLibDir(sThreeJSLibDir) ' Imposto dir di default per libreria Lua e lancio libreria di base Dim sLuaLibsDir As String = String.Empty GetPrivateProfileString(S_LUA, K_LIBSDIR, "", sLuaLibsDir) EgtSetLuaLibs(sLuaLibsDir) Dim sLuaBaseLib As String = String.Empty GetPrivateProfileString(S_LUA, K_BASELIB, "EgtBase", sLuaBaseLib) EgtLuaRequire(sLuaBaseLib) ' Imposto direttorio temporaneo a EgtInterface EgtSetTempDir(m_sTempDir) ' Imposto IniFile a EgtInterface EgtSetIniFile(m_sIniFile) ' Verifico se avviare programma in modalità CAD-ONLY IniFile.m_ProjectMode = If(GetPrivateProfileInt(S_GENERAL, K_ONLYDRAW, 0) = 0, ProjectModeOpt.DRAW, ProjectModeOpt.ONLYDRAW) ' Impostazioni MruLists m_MruFiles.Init(S_MRUFILES, 8) m_MruScripts.Init(S_MRUSCRIPTS, 8) If IniFile.IsActiveDoors() Then m_MruDoors.Init(S_MRUDOORS, 8) End If If IniFile.IsActiveGunStock() Then m_MruNewGunStock.Init(S_MRUGUNSTOCKMOD, 8) m_MruModifyGunStock.Init(S_MRUGUNSTOCKPEZ, 8) End If ' Info su opzioni chiave EgtOutLog("KeyOptions : " & bKey.ToString() & " " & IniFile.m_nKeyOptions.ToString()) End Sub ''' ''' Funzione che permette di gestire il numero di istanze del programma attive contemporaneamente ''' Private Sub ManageInstance() Dim bCreated As Boolean Try m_objMutex = New Mutex(True, "Global\EgtCAM5", bCreated) Catch bCreated = False End Try If bCreated Then ' Prima istanza IniFile.m_nInstance = 1 ' Aggiorno stato istanze attive WritePrivateProfileString(S_GENERAL, K_INSTANCES, IniFile.m_nInstance.ToString) ' Rilascio il possesso del mutex m_objMutex.ReleaseMutex() Else ' Leggo il massimo numero di istanze ammesse Const MAX_INST As Integer = 32 Dim nMaxInst As Integer = GetPrivateProfileInt(S_GENERAL, K_MAXINST, 1) nMaxInst = Max(1, Min(nMaxInst, MAX_INST)) ' Richiedo il possesso del mutex Dim bOk As Boolean = False If m_objMutex.WaitOne(500) Then ' Cerco il primo indice di istanza libero (max 32) Dim nTmp As Integer = GetPrivateProfileInt(S_GENERAL, K_INSTANCES, 0) IniFile.m_nInstance = 1 Dim nMask As Integer = 1 While (nTmp And nMask) <> 0 And IniFile.m_nInstance <= MAX_INST IniFile.m_nInstance += 1 nMask *= 2 End While ' Se nuova istanza nei limiti If IniFile.m_nInstance <= nMaxInst Then bOk = True ' Aggiorno stato istanze attive nTmp += (1 << (IniFile.m_nInstance - 1)) WritePrivateProfileString(S_GENERAL, K_INSTANCES, nTmp.ToString()) End If ' Rilascio il possesso del mutex m_objMutex.ReleaseMutex() End If ' Se non è possibile continuare If Not bOk Then ' porto in primo piano la prima istanza Dim bFound As Boolean = False ' processi del programma a 32 bit Dim localProc As Process() = Process.GetProcessesByName("EgtCAM5R32") For Each p As Process In localProc If p.Id <> Process.GetCurrentProcess().Id Then bFound = True ShowWindow(p.MainWindowHandle, SW.SHOWMAXIMIZED) Exit For End If Next ' se non trovati processi a 32 bit provo a 64 bit If Not bFound Then localProc = Process.GetProcessesByName("EgtCAM5R64") For Each p As Process In localProc If p.Id <> Process.GetCurrentProcess().Id Then bFound = True ShowWindow(p.MainWindowHandle, SW.SHOWMAXIMIZED) Exit For End If Next End If ' esco dal programma Environment.Exit(1) End If End If End Sub Friend Sub NotifyMainWindow_ContentRendered() ' Notifico ProjectVM Map.refProjectVM.ProcessCommandLine() ' Notifico MyMachinePanelVM If IniFile.m_ProjectMode = ProjectModeOpt.ONLYDRAW Then Map.refMachinePanelVM.MachineListIsEnabled = False End If ' Notifico MyStatusBarVM If IniFile.m_bMmUnits Then Map.refStatusBarVM.GridDimensionText = LenToString(IniFile.dSnapStepMm, 4) Else Map.refStatusBarVM.GridDimensionText = LenToString(IniFile.dSnapStepInch, 4) End If ' Notifico TopCommandBarVM If IniFile.m_ProjectMode = ProjectModeOpt.ONLYDRAW Then Map.refTopCommandBarVM.MachiningIsEnabled = False Else Map.refTopCommandBarVM.MachiningIsEnabled = True End If End Sub Friend Sub ManageClosingApplication() ' gestisco la chiusura di SimulationExpanderVM If Not IsNothing(Map.refSimulationExpanderVM) Then If Map.refSimulationExpanderVM.Simulation_IsExpanded Then Map.refSimulationExpanderVM.ResetSimulation() End If End If ' gestisco la chiusura di ProjectVM If Not IniFile.m_bFailedRun Then ' Salvo modo di visualizzazione WritePrivateProfileString(S_SCENE, K_SHOWMODE, EgtGetShowMode().ToString) ' Salvo stato visualizzazione direzione curve WritePrivateProfileString(S_SCENE, K_CURVEDIR, If(EgtGetShowCurveDirection(), 1, 0).ToString) ' Salvo stato visualizzazione griglia WritePrivateProfileString(S_GRID, K_DRAWSHOWGRID, If(IniFile.m_bDrawShowGrid, 1, 0).ToString) WritePrivateProfileString(S_GRID, K_MACHININGSHOWGRID, If(IniFile.m_bMachiningShowGrid, 1, 0).ToString) ' Salvo stato unità di misura per interfaccia utente WritePrivateProfileString(S_SCENE, K_MMUNITS, If(IniFile.m_bMmUnits, 1, 0).ToString) ' Salvo dimensioni griglie in Mm e Inch WritePrivateProfileString(S_GRID, K_SNAPSTEP, DoubleToString(IniFile.dSnapStepMm, 4)) WritePrivateProfileString(S_GRID, K_SNAPSTEPINCH, DoubleToString(IniFile.dSnapStepInch, 4)) End If ' gestisco la chiusura di DrawPanelVM If Not IniFile.m_bFailedRun AndAlso Not IsNothing(Map.refDrawPanelVM) Then WritePrivateProfileString(S_GENERAL, K_DRAW2D, If(Map.refDrawPanelVM.Draw2DIsExpanded, "1", "0")) WritePrivateProfileString(S_GENERAL, K_DRAW3D, If(Map.refDrawPanelVM.Draw3DIsExpanded, "1", "0")) WritePrivateProfileString(S_GENERAL, K_MODIFY, If(Map.refDrawPanelVM.ModifyIsExpanded, "1", "0")) WritePrivateProfileString(S_GENERAL, K_TRANSFORM, If(Map.refDrawPanelVM.TransformIsExpanded, "1", "0")) End If End Sub #End Region #Region "Events" Private Sub MainWindow_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs) ' Con ESC esco dall'azione corrente If e.Key = Key.Escape Then ' reset Azione corrente Map.refProjectVM.ResetStatus() ' reset Analisi e Distanza Map.refInstrumentPanelVM.Analyze_IsChecked(False) Map.refInstrumentPanelVM.GetDistance_IsChecked(False) ' pulisco output Map.refStatusBarVM.NotifyStatusOutput("") Map.refInputExpanderVM.ResetInputBox() End If End Sub #End Region #Region "Verify closing" ''' ''' Should we let our window close? ''' Private m_allowWindowToClose As Boolean = False #End Region #Region "MEF Plugin" Private m_Loader As MEFLoader = New MEFLoader() Private Function GetPathByName(ByVal name As String) As String Dim PluginNameSplit() As String = name.Split("."c) Dim res = Map.refMainWindowVM.m_sDataRoot & "\Plugin\" & PluginNameSplit(0) Return res End Function Friend Function GetControlByName(Of T)(Element As PluginControl) As Panel Dim PlugInControl As Object = m_Loader.LoadByTag(Of T)(GetPathByName(Element.Name), Element.Name).FirstOrDefault() Dim PluginPanel As Panel = Nothing Select Case PlugInControl.GetType().BaseType.FullName Case GetType(Panel).FullName, GetType(Grid).FullName PluginPanel = TryCast(PlugInControl, Panel) Case GetType(Forms.UserControl).FullName Dim PluginUserControl As Forms.UserControl = TryCast(PlugInControl, Forms.UserControl) Dim PluginControlInterface As IPluginControl = TryCast(PlugInControl, IPluginControl) If Not IsNothing(PluginControlInterface) Then AddHandler PluginControlInterface.UpdateProjectName, AddressOf UpdateProjectName AddHandler PluginControlInterface.UpdateUI, AddressOf UpdateUI End If PluginPanel = New WinFormPluginControlV(New WinFormPluginControlVM(PluginUserControl, Element.ViewPanelState)) End Select Return PluginPanel End Function Friend Function GetConfigData(Of T)(ByVal name As String) As IPluginConfigData Dim PlugInControl As Object = m_Loader.LoadByTag(Of T)(GetPathByName(name), name).FirstOrDefault() Dim PluginConfigData As IPluginConfigData = Nothing Dim v = PlugInControl.GetType() If PlugInControl.GetType().Name = PLUGIN_CONFIGURATION_DATA Then Return TryCast(PlugInControl, IPluginConfigData) Else Return Nothing End If End Function Private Sub UpdateProjectName(ProjectName As String) Map.refMainWindowVM.Title = ProjectName & " - EgtCAM5" End Sub Private Sub UpdateUI() Map.refProjectVM.UpdateProjectUI(True) End Sub #End Region ' MEF Plugin End Class