I have several views that could benefit from a base class. Each derived view has this XAML.
<oxy:PlotView x:Name="Plot" Model="{Binding PlotModel}" Grid.Column="2" Loaded="Plot_OnLoaded" Unloaded="Plot_UnLoaded" MinHeight="{Binding MinimumPlotHeight}">
I want this code to be in the base class.
protected void Plot_OnLoaded(object sender, RoutedEventArgs e)
{
foreach (var axis in Plot.ActualModel.Axes)
{
if (axis.Position != AxisPosition.Bottom)
continue;
XAxis = axis;
break;
}
if (XAxis != null)
XAxis.AxisChanged += OnAxisChanged;
}
As you see it references Plot, which the base class has no knowledge of. I tried adding a property to the base class, to let it know what Plot is.
public PlotView Plot { get; set; }
This allows the everything to compile and run, but Plot is just null, which I guess is no surprise. How can I let the base class know about this name in the derived XAML?
I used a variation of Clemens' and BionicCode's suggestions. I defined this property:
public PlotView Plot { get; private set; }
and modified the onloaded handler.
protected void Plot_OnLoaded(object sender, RoutedEventArgs e)
{
Plot = sender as PlotView;
foreach (var axis in Plot.ActualModel.Axes)
{
if (axis.Position != AxisPosition.Bottom)
continue;
XAxis = axis;
break;
}
if (XAxis != null)
XAxis.AxisChanged += OnAxisChanged;
}
I made Plot a public property because I am also using it in the base class here.
protected void OnAxisChanged(object sender, AxisChangedEventArgs e)
{
// if true then stop any recursion
if (IsInternalChange)
return;
var xMin = XAxis.ActualMinimum;
var xMax = XAxis.ActualMaximum;
foreach (SyncrhonisedTrackView track in _parentView.TrackList)
{
if (track == this)
continue;
track.IsInternalChange = true;
// do not use zoom to set axis, it can lead to recursion
track.XAxis.AbsoluteMinimum = xMin;
track.XAxis.AbsoluteMaximum = xMax;
track.Plot.InvalidatePlot(false);
track.IsInternalChange = false;
}
}
Hopefully that will satisfy any design issues.