WPF导航时如何保留ViewModel实例以避免测试中断?
WPF视图导航实例保留问题
问题:每次导航时应用会删除现有视图并创建新实例。当仪表盘运行测试程序时,切换到设置视图再返回,正在运行的测试会被终止,且会初始化新视图实例。需要保留同一视图实例,让测试在用户切换视图时持续运行,但尝试设置静态实例无效。
MainViewModel 实现
class MainVM : ViewModelBase { private object _currentView; public object CurrentView { get { return _currentView; } set { _currentView = value; OnPropertyChanged(); } } public ICommand DashboardCommand { get; set; } public ICommand SettingsCommand { get; set; } public static DashboardVM DashboardInstance { get; } = new DashboardVM(); public static SettingsVM SettingsInstance { get; } = new SettingsVM(); private void Dashboard(object obj) => CurrentView = DashboardInstance; private void Settings(object obj) => CurrentView = SettingsInstance; public MainVM() { DashboardCommand = new RelayCommand(Dashboard); SettingsCommand = new RelayCommand(Settings); // Startup Page CurrentView = DashboardInstance; } }
ViewModelBase 实现
public partial class ViewModelBase : ObservableObject, INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged([CallerMemberName] string propName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName)); } public void NotifyPropertyChanged(string propName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propName)); } } }
MainView 导航部分XAML
<!-- Navigation Panel --> <Grid HorizontalAlignment="Left" Width="76"> <Border Background="#3D5A8A" CornerRadius="10,0,0,10" /> <StackPanel Height="1200" Width="76"> <!-- Dashboard Button --> <nav:Button Style="{StaticResource NavButton_Style}" Command="{Binding DashboardCommand}" IsChecked="True"> <Grid> <Image Source="Images/dash_black_50.png" Style="{StaticResource NavImage_Style}" /> <TextBlock Text="Dashboard" Style="{StaticResource NavText_Style}" /> </Grid> </nav:Button> <!-- Settings Button --> <nav:Button Style="{StaticResource NavButton_Style}" Command="{Binding SettingsCommand}"> <Grid> <Image Source="Images/gear_black_50.png" Style="{StaticResource NavImage_Style}" /> <TextBlock Text="Settings" Style="{StaticResource NavText_Style}" /> </Grid> </nav:Button> </StackPanel> </Grid>
DashboardVM 实现
class DashboardVM : ViewModelBase { enum TestItemStatus { Reset, Queued, InProgress, Pass, Fail } private readonly PageModel _pageModel; private string _StartButtonText, _WaveRelayEthernetText; private bool isTestRunning; public DashboardVM() { _pageModel = new PageModel(); _StartButtonText = "Start Test"; _WaveRelayEthernetText = string.Empty; StartButtonCommand = new RelayCommand(o => StartButtonClick("StartButton")); } #region Text Handlers public string StartButtonText { get { return _StartButtonText; } set { _StartButtonText = value; NotifyPropertyChanged("StartButtonText"); } } public string WaveRelayEthernetText { get { return _WaveRelayEthernetText; } set { _WaveRelayEthernetText = value; NotifyPropertyChanged("WaveRelayEthernetText"); } } #endregion private bool TestRunning { get { return isTestRunning; } set { isTestRunning = value; if (isTestRunning) { StartButtonText = "Stop Test"; } else { StartButtonText = "Start Test"; ResetTestItems(); } NotifyPropertyChanged("TestRunning"); } } public ICommand StartButtonCommand { get; set; } private void StartButtonClick(object sender) { if(TestRunning) { TestRunning = false; } else { SetTestItemsToQueued(); MessageBox.Show("Please plug in Tube 1"); // Start program. TestRunning = true; WaveRelayEthernetText = TestItemStatusEnumToString(TestItemStatus.InProgress); } } private string TestItemStatusEnumToString(TestItemStatus temp) { if (temp == TestItemStatus.Reset) { return string.Empty; } else if (temp == TestItemStatus.Queued) { return "Queued"; } else if (temp == TestItemStatus.InProgress) { return "In Progress"; } else if (temp == TestItemStatus.Pass) { return "Pass"; } else if (temp == TestItemStatus.Fail) { return "Fail"; } else { return string.Empty; } } private void SetTestItemsToQueued() { WaveRelayEthernetText = TestItemStatusEnumToString(TestItemStatus.Queued); } private void ResetTestItems() { WaveRelayEthernetText = TestItemStatusEnumToString(TestItemStatus.Reset); } }

内容的提问来源于stack exchange,提问作者Chip Brommer
相关产品推荐
相关产品推荐

