// -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2014 OxyPlot contributors // // // Represents a control that displays a . // // -------------------------------------------------------------------------------------------------------------------- using Avalonia; namespace OxyPlot.Avalonia { /// /// Represents a control that displays a . /// public class PlotView : PlotBase { /// /// Identifies the dependency property. /// public static readonly StyledProperty ControllerProperty = AvaloniaProperty.Register(nameof(Controller)); /// /// Identifies the dependency property. /// public static readonly StyledProperty ModelProperty = AvaloniaProperty.Register(nameof(Model), null); /// /// The model lock. /// private readonly object modelLock = new object(); /// /// The current model (synchronized with the property, but can be accessed from all threads. /// private PlotModel currentModel; /// /// The default plot controller. /// private IPlotController defaultController; /// /// Initializes static members of the class. /// static PlotView() { PaddingProperty.OverrideMetadata(typeof(PlotView), new StyledPropertyMetadata(new Thickness(8))); ModelProperty.Changed.AddClassHandler(ModelChanged); PaddingProperty.Changed.AddClassHandler(AppearanceChanged); } /// /// Gets or sets the model. /// /// The model. public PlotModel Model { get { return GetValue(ModelProperty); } set { SetValue(ModelProperty, value); } } /// /// Gets or sets the Plot controller. /// /// The Plot controller. public IPlotController Controller { get { return GetValue(ControllerProperty); } set { SetValue(ControllerProperty, value); } } /// /// Gets the actual model. /// /// The actual model. public override PlotModel ActualModel { get { return currentModel; } } /// /// Gets the actual PlotView controller. /// /// The actual PlotView controller. public override IPlotController ActualController { get { return Controller ?? (defaultController ?? (defaultController = new PlotController())); } } /// /// Called when the visual appearance is changed. /// protected void OnAppearanceChanged() { InvalidatePlot(false); } /// /// Called when the visual appearance is changed. /// /// The d. /// The instance containing the event data. private static void AppearanceChanged(AvaloniaObject d, AvaloniaPropertyChangedEventArgs e) { ((PlotView)d).OnAppearanceChanged(); } /// /// Called when the model is changed. /// /// The sender. /// The instance containing the event data. private static void ModelChanged(AvaloniaObject d, AvaloniaPropertyChangedEventArgs e) { ((PlotView)d).OnModelChanged(); } /// /// Called when the model is changed. /// private void OnModelChanged() { lock (modelLock) { if (currentModel != null) { ((IPlotModel)currentModel).AttachPlotView(null); currentModel = null; } if (Model != null) { ((IPlotModel)Model).AttachPlotView(null); // detach so we can re-attach ((IPlotModel)Model).AttachPlotView(this); currentModel = Model; } } InvalidatePlot(); } } }