防止WPF ViewModel在导航到其他视图时创建新示例

jdzmm42g  于 2023-02-13  发布在  其他
关注(0)|答案(1)|浏览(181)

我正在尝试阻止我的应用程序删除视图,然后在每次导航时创建一个新视图。我有一个 Jmeter 板,如果我选择设置视图,它将运行测试程序,然后返回 Jmeter 板。它已经删除了正在运行的测试并初始化了一个新视图。我需要保持相同的视图示例处于活动状态,以便在用户导航到设置视图并再次返回时测试可以继续运行,但我无法确切地弄清楚如何成功地做到这一点我尝试过将示例设置为静态的,但似乎没有什么不同。
主视图模型

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;
        }
}

查看模型库

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));
            }
        }
    }

主视图-导航

<!-- 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>

控制面板虚拟机

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);
        }
    }

参考图片:

ia2d9nvy

ia2d9nvy1#

我的问题是在App.xaml中,我链接了一个DataTemplate文件,如下所示:

<ResourceDictionary Source="Utilities/DataTemplate.xaml" />

在数据模板中,我有这样的代码,它将视图链接到视图模型。

<ResourceDictionary [...]">
    <DataTemplate DataType="{x:Type vm:DashboardVM}">
        <view:Dashboard />
    </DataTemplate>
    <DataTemplate DataType="{x:Type vm:SettingsVM}">
        <view:Settings />
    </DataTemplate>
</ResourceDictionary>

我修改了代码,将两者联系起来:

<ResourceDictionary [...]>
    <view:Dashboard x:Key="DashboardViewKey"/>
    <view:Settings x:Key="SettingsViewKey"/>
    <DataTemplate DataType="{x:Type vm:DashboardVM}">
        <ContentControl Content="{StaticResource DashboardViewKey}" />
    </DataTemplate>
    <DataTemplate DataType="{x:Type vm:SettingsVM}">
        <ContentControl Content="{StaticResource SettingsViewKey}" />
    </DataTemplate>
</ResourceDictionary>

我现在收到了预期的行为,即能够在不调用 Jmeter 板构造函数的情况下进行导航,因此视图不会破坏和重新创建。
希望其他人觉得这个有用。

相关问题