I recently posted a video demonstrating how to implement some extension methods to support xamDataChart navigation. The navigation support implemented in the demo included:
The only problem with the code I used in the video, was that the event handler for the buttons included a long if statement to handle navigation support. As the famous quote goes, “If it smells, it’s bad code”, so I wanted to refactor the implementation to be a bit more maintainable. Before I get into the changes, I first want to list the extension methods that I implemented in order to make it easy to pan and zoom the chart. Notice that the methods us a default scale value so you are not required to pass in a scale amount for each method call.
public static class xamDataChartExtensions { private static double _defaultScale = 0.05; public static void ZoomIn(this XamDataChart dataChart) { ZoomIn(dataChart, _defaultScale); } public static void ZoomIn(this XamDataChart dataChart, double scale) { dataChart.WindowScaleHorizontal -= scale; dataChart.WindowScaleVertical -= scale; } public static void ZoomOut(this XamDataChart dataChart) { ZoomOut(dataChart, _defaultScale); } public static void ZoomOut(this XamDataChart dataChart, double scale) { dataChart.WindowScaleHorizontal += scale; dataChart.WindowScaleVertical += scale; } public static void PanUp(this XamDataChart dataChart) { PanUp(dataChart, _defaultScale); } public static void PanUp(this XamDataChart dataChart, double scale) { dataChart.WindowPositionVertical -= scale; } public static void PanDown(this XamDataChart dataChart) { PanDown(dataChart, _defaultScale); } public static void PanDown(this XamDataChart dataChart, double scale) { dataChart.WindowPositionVertical += scale; } public static void PanLeft(this XamDataChart dataChart) { PanLeft(dataChart, _defaultScale); } public static void PanLeft(this XamDataChart dataChart, double scale) { dataChart.WindowPositionHorizontal -= scale; } public static void PanRight(this XamDataChart dataChart) { PanRight(dataChart, _defaultScale); } public static void PanRight(this XamDataChart dataChart, double scale) { dataChart.WindowPositionHorizontal += scale; }
The previous code I implemented featured a nested if statement that would call the appropriate extension method, but I knew there was an easy way to clean this code out of the page. The key to a more concise approach begins by defining a enumeration which lists the navigation options:
public enum xamDataChartNavigationTypes { PanUp, PanDown, PanLeft, PanRight, ZoomIn, ZoomOut, FitInWindow, Undefined }
Now armed with the navigation enumeration I added another extension method named Navigate which takes an instance of the navigation enumeration and an option to pass an explicit scale value:
public static void Navigate(this XamDataChart dataChart, xamDataChartNavigationTypes navigationType) { Navigate(dataChart, navigationType, _defaultScale); } public static void Navigate(this XamDataChart dataChart, xamDataChartNavigationTypes navigationType, double scale) { switch (navigationType) { case xamDataChartNavigationTypes.FitInWindow: dataChart.WindowRect = new Rect(0, 0, 1, 1); break; case xamDataChartNavigationTypes.PanUp: dataChart.PanUp(scale); break; case xamDataChartNavigationTypes.PanDown: dataChart.PanDown(scale); break; case xamDataChartNavigationTypes.PanLeft: dataChart.PanLeft(scale); break; case xamDataChartNavigationTypes.PanRight: dataChart.PanRight(scale); break; case xamDataChartNavigationTypes.ZoomIn: dataChart.ZoomIn(scale); break; case xamDataChartNavigationTypes.ZoomOut: dataChart.ZoomOut(scale); break; default: break; } }
Now as long at the Tag property of your button is equal to one of the navigation enumeration values (ex: PanUp, PanDown, etc), then the click handler is reduced to the following:
private void Navigate_Click(object sender, RoutedEventArgs e) { string tag = (sender as Button).Tag.ToString(); xamDataChartNavigationTypes navigationType; if (xamDataChartNavigationTypes.TryParse(tag, out navigationType)) { this.dataChart.Navigate(navigationType); } }