Reputation: 23
I have a series that I want to make visible or invisible by checking a box. It is a simple project with XAML and the "code behind" .cs file. When I'm checking or unchecking the box, the isVisible
property changes it's value properly to true or false depending on the action.
OnPropertyChanged()
fires too, but it's handler is always null no matter if I set MainChart
to something new or change the isVisible
value.
In the other question on stack I saw that someone suggested that using ItemSource
helps, but I'm not sure how I can use it in code behind and it also seems that simply invalidating the plot should work.
The project itself consists of multiple files but I think 2 are essential to the problem:
MainWindow.xaml:
<Window x:Class="NeoracerLogsExplorer.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:NeoracerLogsExplorer"
xmlns:oxy="http://oxyplot.org/wpf"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<local:MainWindow/>
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="2*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" Grid.Row="0" Grid.Column="0">
<StackPanel Orientation="Vertical" Margin="10">
<Label FontWeight="Bold">Leg preassures</Label>
<CheckBox x:Name ="LeftLegCheckBox" IsChecked="True" Checked="LeftLegCheckBox_CheckedChanged"
Unchecked="LeftLegCheckBox_CheckedChanged">Left leg pressure</CheckBox>
<CheckBox x:Name ="RightLegCheckBox">Right leg pressure</CheckBox>
</StackPanel>
<StackPanel Orientation="Vertical" Margin="10">
<Label FontWeight="Bold">Pillow pressures</Label>
<CheckBox x:Name ="LeftPillowCheckBox" IsChecked="True">Left pillow pressure</CheckBox>
<CheckBox x:Name ="RightPillowCheckBox">Right pillow pressure</CheckBox>
<CheckBox x:Name ="FrontPillowCheckBox">Front pillow pressure</CheckBox>
<CheckBox x:Name ="BackPillowCheckBox">Back pillow pressure</CheckBox>
</StackPanel>
<StackPanel Orientation="Vertical" Margin="10">
<Label FontWeight="Bold">Game event types</Label>
<CheckBox x:Name ="NoneEventCheckBox">None game events</CheckBox>
<CheckBox x:Name ="DodgeEventCheckBox" IsChecked="True">Dodge game events</CheckBox>
<CheckBox x:Name ="CrashEventCheckBox" IsChecked="True">Crash game events</CheckBox>
<CheckBox x:Name ="OtherEventCheckBox">Other game events</CheckBox>
</StackPanel>
</StackPanel>
<oxy:PlotView x:Name="MainChartArea" Grid.Row ="1" Grid.Column="0" Model="{Binding MainChart}"/>
</Grid>
</Window>
MainWindow.xaml.cs:
using NeoracerLogsExplorer.Charts;
using NeoracerLogsExplorer.GameEvents;
using OxyPlot;
using OxyPlot.Series;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
using System.Diagnostics;
namespace NeoracerLogsExplorer
{
public partial class MainWindow : Window, INotifyPropertyChanged
{
private const char DIRECTORY_NAME_SEPARATOR = '\\';
private const char FILE_EXTENTION_SEPARATOR = '.';
private const string GAME_EVENTS_LOG_DIRECTORY = "GameEventsLogs";
private const string GAME_EVENTS_LOG_FILE_NAME = "neoracer_game_events";
private const string GAME_EVENTS_LOG_FILE_EXTENTION = "log";
public event PropertyChangedEventHandler PropertyChanged;
private GameEventsManager gameEventsManager;
private ChartManager chartManager;
private Chart mainChart;
public MainWindow()
{
//InitializeComponent();
gameEventsManager = new GameEventsManager();
string gameEventsLogFilePath = GetGameEventsLogFilePath();
gameEventsManager.RetrieveGameEventsFromFile(gameEventsLogFilePath);
Debug.WriteLine("TEST!");
Debug.WriteLine(gameEventsLogFilePath);
List<GameEvent> gameEvents = gameEventsManager.GameEvents;
chartManager = new ChartManager(gameEvents);
mainChart = chartManager.CreateAllSensorsChart();
this.DataContext = this;
}
//[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
public Chart MainChart
{
get { return mainChart; }
set { mainChart = value; }
}
private void LeftLegCheckBox_CheckedChanged(object sender, RoutedEventArgs args)
{
if (LeftLegCheckBox.IsChecked == true)
{
mainChart.LeftLegPressureLineSeriesVisibility(true);
}
else
{
mainChart.LeftLegPressureLineSeriesVisibility(false);
}
//MainChart = mainChart;
MainChart.InvalidatePlot(false);
OnPropertyChanged(nameof(MainChart));
}
public string GetGameEventsLogFilePath()
{
string currentGameEventsLogDirectoryPath =
Environment.CurrentDirectory
+ DIRECTORY_NAME_SEPARATOR
+ GAME_EVENTS_LOG_DIRECTORY
+ DIRECTORY_NAME_SEPARATOR;
string currentGameEventsLogFileName =
GAME_EVENTS_LOG_FILE_NAME
+ FILE_EXTENTION_SEPARATOR
+ GAME_EVENTS_LOG_FILE_EXTENTION;
string gameEventsLogFilePath =
currentGameEventsLogDirectoryPath
+ currentGameEventsLogFileName;
return gameEventsLogFilePath;
}
}
}
Chart
inherits from OxyPlot.PlotModel
.
LeftLegPressureLineSeriesVisibility looks like this:
public void LeftLegPressureLineSeriesVisibility(bool isVisible)
{
leftLegPressureLineSeries.IsVisible = isVisible;
}
If you need more information let me know. I can even send you a project file somewhere if needed. (I'm not sure if you can do this on stack)
It seems that invalidatePlot doesn't recognize the plotView because this.PlotView
is null here :
public void InvalidatePlot(bool updateData)
{
var plotView = this.PlotView;
if (plotView == null)
{
return;
}
plotView.InvalidatePlot(updateData);
}
Did I construct my custom series wrong ? Are there any rules to do it ? Any ideas ?
Upvotes: 0
Views: 71