You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 07:05:24