using MainShell.Common; using MainShell.Models; using MainShell.Recipe.Models; using MaxwellFramework.Core.Interfaces; using MwFramework.ManagerService; using Stylet; using StyletIoC; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; namespace MainShell.Recipe.ViewModel { public class RecipeViewModel :BaseScreen ,IPage { private bool _isReactivatingAfterBlockedLeave; public string Name => "Recipe"; private const string CARRIER = "载具配方"; private const string SUBSTRATE = "基板配方"; private const string WAFER = "芯片配方"; private const string PROCESS = "工艺配方"; private readonly Dictionary _viewModelDict = new Dictionary(); public ObservableCollection MenuItemWraps { get; private set; } private MenuItemWrap _selectedMenuItem; public MenuItemWrap SelectedMenuItem { get { return _selectedMenuItem; } set { if (_selectedMenuItem == value) return; if (_selectedMenuItem != null && value != null && !TryLeaveCurrentScreen()) { NotifyOfPropertyChange(() => SelectedMenuItem); return; } if (SetAndNotify(ref _selectedMenuItem, value)) { CurrentScreen = value != null ? _viewModelDict[value.Header] : null; SyncCurrentScreenSelectionFromActiveRecipe(); } } } private BaseScreen _currentScreen; public BaseScreen CurrentScreen { get { return _currentScreen; } set { if (_currentScreen == value) return; UnsubscribeScreenState(_currentScreen as INotifyPropertyChanged); if (SetAndNotify(ref _currentScreen, value)) { SubscribeScreenState(value as INotifyPropertyChanged); NotifyOfPropertyChange(() => IsRecipePanelHidden); } } } public bool IsRecipePanelHidden { get { var recipeScreen = CurrentScreen as IRecipeViewModel; return recipeScreen != null && recipeScreen.HideRecipePanel; } set { var recipeScreen = CurrentScreen as IRecipeViewModel; if (recipeScreen == null || recipeScreen.HideRecipePanel == value) return; recipeScreen.HideRecipePanel = value; NotifyOfPropertyChange(() => IsRecipePanelHidden); } } private CarrierRecipeViewModel _carrierRecipeViewModel; [Inject] public CarrierRecipeViewModel CarrierRecipeViewModel { get { return _carrierRecipeViewModel; } set { _carrierRecipeViewModel = value; } } private SubstrateRecipeViewModel _substrateRecipeViewModel; [Inject] public SubstrateRecipeViewModel SubstrateRecipeViewModel { get { return _substrateRecipeViewModel; } set { _substrateRecipeViewModel = value; } } private WaferRecipeViewModel _waferRecipeViewModel; [Inject] public WaferRecipeViewModel WaferRecipeViewModel { get { return _waferRecipeViewModel; } set { _waferRecipeViewModel = value; } } private ProcessRecipeViewModel _processRecipeViewModel; [Inject] public ProcessRecipeViewModel ProcessRecipeViewModel { get { return _processRecipeViewModel; } set { _processRecipeViewModel = value; } } public RecipeViewModel() { InitMenuItems(); } protected override void OnViewLoaded() { base.OnViewLoaded(); EnsureViewModelDict(); if(SelectedMenuItem==null) SelectedMenuItem = MenuItemWraps[0]; SyncCurrentScreenSelectionFromActiveRecipe(); } private void InitMenuItems() { MenuItemWraps = new ObservableCollection { //new MenuItemWrap() { Header=CARRIER,Tag=CARRIER }, new MenuItemWrap() { Header=SUBSTRATE,Tag=SUBSTRATE }, new MenuItemWrap() { Header=WAFER,Tag=WAFER }, new MenuItemWrap() { Header=PROCESS,Tag=PROCESS }, }; } private void InitViewModelDict() { _viewModelDict.Clear(); _viewModelDict.Add(CARRIER, CarrierRecipeViewModel); _viewModelDict.Add(SUBSTRATE, SubstrateRecipeViewModel); _viewModelDict.Add(WAFER, WaferRecipeViewModel); _viewModelDict.Add(PROCESS, ProcessRecipeViewModel); } private void EnsureViewModelDict() { if (_viewModelDict.Count == 0) { InitViewModelDict(); } } private void SyncCurrentScreenSelectionFromActiveRecipe() { var recipeScreen = CurrentScreen as IRecipeViewModel; recipeScreen?.SyncSelectionFromActiveRecipe(); } private bool TryLeaveCurrentScreen() { var guard = CurrentScreen as IRecipeViewModel; if (guard == null) return true; return guard.TryLeaveCurrentRecipeContext(); } public bool TrySelectMenuItem(MenuItemWrap targetMenuItem) { if (targetMenuItem == null) return false; SelectedMenuItem = targetMenuItem; return SelectedMenuItem == targetMenuItem; } public bool TrySelectRecipeWrap(RecipeWrap targetRecipeWrap) { var guard = CurrentScreen as IRecipeViewModel; if (guard == null || targetRecipeWrap == null) return false; if (guard.SelectedRecipeWrap == targetRecipeWrap) return true; guard.SelectedRecipeWrap = targetRecipeWrap; return guard.SelectedRecipeWrap == targetRecipeWrap; } private void SubscribeScreenState(INotifyPropertyChanged screen) { if (screen != null) { screen.PropertyChanged += OnCurrentScreenPropertyChanged; } } private void UnsubscribeScreenState(INotifyPropertyChanged screen) { if (screen != null) { screen.PropertyChanged -= OnCurrentScreenPropertyChanged; } } private void OnCurrentScreenPropertyChanged(object sender, PropertyChangedEventArgs e) { if (string.IsNullOrWhiteSpace(e.PropertyName) || string.Equals(e.PropertyName, nameof(BaseScreen.HideRecipePanel), StringComparison.Ordinal)) { NotifyOfPropertyChange(() => IsRecipePanelHidden); } } protected override void OnStateChanged(ScreenState previousState, ScreenState newState) { base.OnStateChanged(previousState, newState); if (_isReactivatingAfterBlockedLeave) return; if (newState == ScreenState.Active) { EnsureViewModelDict(); if (SelectedMenuItem == null && MenuItemWraps != null && MenuItemWraps.Count > 0) { SelectedMenuItem = MenuItemWraps[0]; } SyncCurrentScreenSelectionFromActiveRecipe(); } if (previousState == ScreenState.Active && newState == ScreenState.Deactivated && !TryLeaveCurrentScreen()) { try { _isReactivatingAfterBlockedLeave = true; Execute.OnUIThread(() => ((IScreenState)this).Activate()); } finally { _isReactivatingAfterBlockedLeave = false; } } } protected override void OnDeactivate() { UnsubscribeScreenState(_currentScreen as INotifyPropertyChanged); base.OnDeactivate(); } } }