我的 MVVM 有问题,我无法从另一个 ViewModel 更改一个 ViewModel 的 props,UI 没有更新

问题描述 投票:0回答:1

我有很多关于我的 MVVM 的问题,我无法传递任何 props,或者如果我仍然将它们从一个 ViewModel 传递到另一个 ViewModel,它仍然没有更新 UI。

例如这里:

我的 xaml 文件:

<UserControl.DataContext>
  <viewModels:PlotViewModel  />
</UserControl.DataContext>

<Border Grid.Row="0">
            <oxy:PlotView Name="SpectralPlot"
                          Width="Auto"
                          Height="Auto"
                          HorizontalAlignment="Stretch"
                          VerticalAlignment="Stretch"
                          Background="Transparent"
                          Model="{Binding SpectralPlotModel, UpdateSourceTrigger=PropertyChanged}"
                          Visibility="{Binding IsSpectralPlotVisible, UpdateSourceTrigger=PropertyChanged}" />

        </Border>

        <Border Grid.Row="0">
            <oxy:PlotView Name="SpectralAEPlot"
                          Width="Auto"
                          Height="Auto"
                          HorizontalAlignment="Stretch"
                          VerticalAlignment="Stretch"
                          Background="Transparent"
                          Model="{Binding SpectralAEPlotModel, UpdateSourceTrigger=PropertyChanged}"
                          Visibility="{Binding IsSpectralAEPlotVisible, UpdateSourceTrigger=PropertyChanged}" />
        </Border>

<UserControl.DataContext>
  <viewModels:AEViewModel />
</UserControl.DataContext>
<!-- Lock -->
<Button Content="Back to Plot"
        Margin="0,10,0,0"
        Width="170"
        Height="45"
        Grid.Row="0"
        Grid.Column="0"
        Visibility="{Binding GoBackButtonVisibility}"
        Command="{Binding GoBackCommand,UpdateSourceTrigger=PropertyChanged}" />
<Button Content="Lock"
        Margin="0,10,0,0"
        Width="170"
        Height="45"
        Grid.Row="0"
        Grid.Column="0"
        Visibility="{Binding LockButtonVisibility}"
        Command="{Binding LockCommand,UpdateSourceTrigger=PropertyChanged}" />

我的 ViewModel 类:

namespace InteWPF.ViewModel.Components
{
    public class PlotViewModel : ObservableObject, IDisposable
    {
        // ====================== About Plot ======================
        private DispatcherTimer _timer;
        private bool _isTracking;
        private bool _isPaused;
        private bool _locked = false;
        private bool _stopAll = false;
        private bool _isLocked = false;
        private DataPoint _nearestPoint = new DataPoint(0,0);
        private DataPoint near = new DataPoint(0, 0);
        private ScreenPoint mouseDownPoint;
        private int waveLengthIndex;
        private bool mouseWavelengthClick = false;

        public PlotViewModel()
        {
            SpectralPlotModel = new PlotModel
            {
                Title = "Sweep",
                Background = OxyColors.Transparent,
                TextColor = OxyColors.White,
                PlotAreaBorderColor = OxyColors.White
            };

            SpectralPlotModel.Axes.Add(new LinearAxis
            {
                Position = AxisPosition.Bottom,
                Title = "Wavelength",
                TitleColor = OxyColors.White,
                AxislineColor = OxyColors.White,
                TextColor = OxyColors.White,
                TicklineColor = OxyColors.White,
                StringFormat = "0.###",
                Minimum = 1546,
                Maximum = 1558
            });

            SpectralPlotModel.Axes.Add(new LinearAxis
            {
                Position = AxisPosition.Left,
                Title = "Arbitrary Units",
                TitleColor = OxyColors.White,
                AxislineColor = OxyColors.White,
                TextColor = OxyColors.White,
                TicklineColor = OxyColors.White,
                StringFormat = "0.###",
                Minimum = 0,
                Maximum = 5,
            });

            SpectralPlotModel.Series.Add(new LineSeries
            {
                Title = "Data",
                Color = OxyColors.White,
                MarkerFill = OxyColors.White,
                MarkerType = MarkerType.None,
                LineStyle = LineStyle.Solid,
                StrokeThickness = 2,
            });

            SpectralPlotModel.MouseDown += MyPlotModel_MouseDown;

            SpectralAEPlotModel = new PlotModel
            {
                Title = "AE",
                Background = OxyColors.Transparent,
                TextColor = OxyColors.White,
                PlotAreaBorderColor = OxyColors.White
            };

            SpectralAEPlotModel.Axes.Add(new LinearAxis
            {
                Position = AxisPosition.Bottom,
                Title = "Time",
                TitleColor = OxyColors.White,
                AxislineColor = OxyColors.White,
                TextColor = OxyColors.White,
                TicklineColor = OxyColors.White,
                StringFormat = "0.###",
            });

            SpectralAEPlotModel.Axes.Add(new LinearAxis
            {
                Position = AxisPosition.Left,
                Title = "Amplitude",
                TitleColor = OxyColors.White,
                AxislineColor = OxyColors.White,
                TextColor = OxyColors.White,
                TicklineColor = OxyColors.White,
                StringFormat = "0.###",
            });

            SpectralAEPlotModel.Series.Add(new LineSeries
            {
                Title = "AE Data",
                Color = OxyColors.White,
                MarkerFill = OxyColors.White,
                MarkerType = MarkerType.None,
                LineStyle = LineStyle.Solid,
                StrokeThickness = 2,
            });
            // ====================== Commands ======================
            ScanCommand = new RelayCommand(o => ExecuteScan());
            PauseCommand = new RelayCommand(o => ExecutePause());
            SaveSpectrumCommand = new RelayCommand(o => ExecuteSaveSpectrum());
            SavePngCommand = new RelayCommand(o => ExecuteSavePng());
            SettingsCommand = new RelayCommand(o => ExecuteSettings());
            LockCommand = new RelayCommand(o => OnLockChanged(0,0));
            GoBackCommand = new RelayCommand(o => OnGoBackChanged());
        }       

        private void MyPlotModel_MouseDown(object sender, OxyMouseDownEventArgs ex)
        {
            //mouseWavelengthClick = true;
            OxyPlot.ElementCollection<OxyPlot.Axes.Axis> axisList = SpectralPlotModel.Axes;

            Axis xAxis = axisList.FirstOrDefault(ax => ax.Position == AxisPosition.Bottom);
            Axis yAxis = axisList.FirstOrDefault(ax => ax.Position == AxisPosition.Left);

            NearestPoint = OxyPlot.Axes.Axis.InverseTransform(ex.Position, xAxis, yAxis);
            //Debug.Print("Nearest Point: " + NearestPoint);
        }


        public async void OnLockChanged(int scanWindow, int intesityThreshold)
        {
            //Debug.Print("Wavelength Index: "+waveLengthIndex);
            //Debug.Print($"Points: {NearestPoint}, scanWindowSeconds: {scanWindow},Threshold: {intesityThreshold}");
            Debug.Print("Lock ..!");
            Debug.Print("IsSpectralPlotVisible: "+ IsSpectralPlotVisible);
            Debug.Print("IsSpectralAEPlotVisible: " + IsSpectralAEPlotVisible);
            //IsSpectralPlotVisible = Visibility.Collapsed;
            //IsSpectralAEPlotVisible = Visibility.Visible;
            Debug.Print("IsSpectralPlotVisible: " + IsSpectralPlotVisible);
            Debug.Print("IsSpectralAEPlotVisible: " + IsSpectralAEPlotVisible);
            await AEHTTP.SendAEValues(new DataPoint(1552,0.4), scanWindow, intesityThreshold);
            await UpdateAEPlotAsync(IP, 4004);
        }


        public async void OnGoBackChanged()
        {
            Debug.Print("Go Back ..!");
            Debug.Print("IsSpectralPlotVisible: " + IsSpectralPlotVisible);
            Debug.Print("IsSpectralAEPlotVisible: " + IsSpectralAEPlotVisible);
            //IsSpectralPlotVisible = Visibility.Visible;
            //IsSpectralAEPlotVisible = Visibility.Collapsed;
            Debug.Print("IsSpectralPlotVisible: " + IsSpectralPlotVisible);
            Debug.Print("IsSpectralAEPlotVisible: " + IsSpectralAEPlotVisible);
        }
       
        // ====================== Getters Setters ======================
        // ====================== Commands ======================
        public ICommand ScanCommand { get; }
        public ICommand PauseCommand { get; }
        public ICommand SaveSpectrumCommand { get; }
        public ICommand SavePngCommand { get; }
        public ICommand SettingsCommand { get; }
        public ICommand LockCommand { get; }
        public ICommand GoBackCommand { get; }
        // ====================== Plotters ======================
        public PlotModel SpectralPlotModel { get; set; }
        public PlotModel SpectralAEPlotModel { get; set; }
        // ====================== About Nearest Point Visibility ======================
        public DataPoint NearestPoint
        {
            get
            {
                Debug.Print($"Entered Get {_nearestPoint}!!!"); 
                return _nearestPoint; 
            }
            set
            {
                Debug.Print($"Entered Set {value}!!!");
                _nearestPoint = value;
                OnPropertyChanged();
                //OnPropertyChanged(nameof(NearestPoint));
             }
        }
        // ====================== About Plot Visibility ======================
        public Visibility IsSpectralPlotVisible { get; set; }
        public Visibility IsSpectralAEPlotVisible { get; set; }

        //private Visibility _isSpectralPlotVisible = Visibility.Visible;
        //private Visibility _isSpectralAEPlotVisible = Visibility.Collapsed;
        //public Visibility IsSpectralPlotVisible
        //{
        //    get => _isSpectralPlotVisible;
        //    set
        //    {
        //            _isSpectralPlotVisible = value;
        //            OnPropertyChanged();
        //    }
        //}
        //public Visibility IsSpectralAEPlotVisible
        //{
        //    get => _isSpectralAEPlotVisible;
        //    set
        //    {
        //            _isSpectralAEPlotVisible = value;
        //            OnPropertyChanged();
        //    }
        //}

namespace InteWPF.ViewModel.Screens
{
    public class AEViewModel : ObservableObject
    {
        // Variables
        private PlotViewModel _plotViewModel { get; set; }

        private bool _isLocked;
        private int _scanWindow;
        private int _intesityThreshold;


        private Visibility _goBackButtonVisibility = Visibility.Collapsed;
        private Visibility _lockButtonVisibility = Visibility.Visible;
        public Visibility GoBackButtonVisibility
        {
            get => _goBackButtonVisibility;
            set
            {
                _goBackButtonVisibility = value;
                OnPropertyChanged();
            }
        }
        public Visibility LockButtonVisibility
        {
            get => _lockButtonVisibility;
            set
            {
                _lockButtonVisibility = value;
                OnPropertyChanged();
            }
        }

        public AEViewModel () 
        {
            _plotViewModel = new PlotViewModel();
            LockCommand = new RelayCommand(ExecuteLockCommand);
            GoBackCommand = new RelayCommand(ExecuteGoBackCommand);
        }

        public int ScanWindow
        {
            get => _scanWindow;
            set
            {
                if (_scanWindow != value)
                {
                    _scanWindow = value;
                    OnPropertyChanged();
                }
            }
        }
        public int IntesityThreshold
        {
            get => _intesityThreshold;
            set
            {
                if (_intesityThreshold != value)
                {
                    _intesityThreshold = value;
                    OnPropertyChanged();
                }
            }
        }

        //ICommand
        public ICommand LockCommand { get; }
        public ICommand GoBackCommand { get; }
        private void ExecuteLockCommand(object parameter)
        {
            _plotViewModel.OnLockChanged(_scanWindow, _intesityThreshold);
            _plotViewModel.IsSpectralPlotVisible = Visibility.Collapsed;
            _plotViewModel.IsSpectralAEPlotVisible = Visibility.Visible;
            GoBackButtonVisibility = Visibility.Visible;
            LockButtonVisibility = Visibility.Collapsed;
        }
        private void ExecuteGoBackCommand(object parameter)
        {
            _plotViewModel.OnGoBackChanged();
            _plotViewModel.IsSpectralPlotVisible = Visibility.Visible;
            _plotViewModel.IsSpectralAEPlotVisible = Visibility.Collapsed;
            GoBackButtonVisibility = Visibility.Collapsed;
            LockButtonVisibility = Visibility.Visible;
        }
    }
}

我无法隐藏 - 折叠我的第二个图,我希望当用户单击“锁定”按钮时隐藏第一个图并显示第二个图,如果用户按“返回”按钮执行相反的操作。

我认为这是我的 MVVM 架构的问题还是异步的问题? 因为当我尝试使用 MyPlotModel_MouseDown 函数传递 NearestPoint 时,我也无法将值获取到 OnLockChanged 函数以便使用它。

任何帮助将不胜感激。谢谢!

c# wpf oxyplot
1个回答
0
投票

为了让接口在属性更改时发生更改,它必须知道它。简单地改变一个变量不会有任何作用。使用 INotifyPropertyChanged 通知接口属性值已更改: 公共事件 PropertyChangedEventHandler PropertyChanged;

public class PlotViewModel : ObservableObject, IDisposable, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
         PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    private Visibility isSpectralPlotVisible;
    private Visibility isSpectralAEPlotVisible;

    public Visibility IsSpectralPlotVisible
    {
        get => isSpectralPlotVisible;
        set
        {
            isSpectralPlotVisible = value;
            OnPropertyChanged(nameof(IsSpectralPlotVisible));
        }
    }
    public Visibility IsSpectralAEPlotVisible
    {
        get => isSpectralAEPlotVisible;
        set
        {
            isSpectralAEPlotVisible = value;
            OnPropertyChanged(nameof(IsSpectralAEPlotVisible));
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.