我有很多关于我的 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 函数以便使用它。
任何帮助将不胜感激。谢谢!
为了让接口在属性更改时发生更改,它必须知道它。简单地改变一个变量不会有任何作用。使用 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));
}
}