Живые графики WPF - разделитель привязки в коде не работает - PullRequest
0 голосов
/ 04 мая 2018

Использование Live Charts 0.9.7 - и .NET 4.5

Я пытаюсь добавить разделитель с помощью кода к оси и связать значение шага разделителя в коде, потому что я динамически добавляю новые ряды в декартову зависимость во время выполнения. Разделитель будет меняться в зависимости от размера набора данных.

Вот мой код:

public partial class PlottingTool : UserControl, INotifyPropertyChanged
{
    public static SeriesCollection SeriesCollection { get; set; }

    #region LineSeries1Specifics

    private double _lineSeries1XAxisSeparatorStep;

    // Separator for x-axis
    public double LineSeries1XAxisSeparatorStep     // Bind the separator for the x-axis to this.
    {
        get
        {
            return _lineSeries1XAxisSeparatorStep;
        }
        set
        {
            _lineSeries1XAxisSeparatorStep = value;
            OnPropertyChanged("LineSeries1AxisSeparatorStep");
        }
    }

    #endregion





    public PlottingTool()
    {
        InitializeComponent();

        // Setup Chart
        SetupChart();

        // DataContext for the liveChart
        DataContext = this;
    }

    private void SetupChart()
    {
        // Create an empty series collection.
        SeriesCollection = new SeriesCollection();

        // Setup the axis for the first chart
        ChartFile.AxisX.Add(new Axis
        {
            Title = "Time",
            Unit = TimeSpan.FromSeconds(1).Seconds,
            Separator = new LiveCharts.Wpf.Separator
            {
                IsEnabled = true
            },
            DisableAnimations = true

        });

        ChartFile.AxisY.Add(new Axis
        {
            Unit = 1,
            DisableAnimations = true
        });

        // Bind the series1 separator to the x-axis for the first chart
        Binding xAxisSeparatorBinding = new Binding();
        xAxisSeparatorBinding.Source = this;
        xAxisSeparatorBinding.Path = new PropertyPath("LineSeries1XAxisSeparatorStep");
        xAxisSeparatorBinding.Mode = BindingMode.OneWay;
        xAxisSeparatorBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
        BindingOperations.SetBinding(ChartFile.AxisX[0].Separator, LiveCharts.Wpf.Separator.StepProperty, xAxisSeparatorBinding);

    }



    #region INotifyPropertyChanged Members
    public event PropertyChangedEventHandler PropertyChanged;

    /// <summary>
    /// Raises this object's PropertyChanged event.
    /// </summary>
    /// <param name="propertyName">The property that has a new value.</param>
    protected void OnPropertyChanged([CallerMemberName]string propertyName = null)
    {
        PropertyChangedEventHandler handler = this.PropertyChanged;

        if (handler != null)
        {

            var e = new PropertyChangedEventArgs(propertyName);
            handler(this, e);
        }
    }


    #endregion

    }

XAML код:

<UserControl x:Class="DataAnalyzer.Controls.PlottingTool"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:DataAnalyzer.Controls"
         xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"
         mc:Ignorable="d" 
         d:DesignHeight="450" d:DesignWidth="800">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"></RowDefinition>
    </Grid.RowDefinitions>
    <lvc:CartesianChart Name="ChartFile" Series="{Binding SeriesCollection}" Grid.Row="0" LegendLocation="Top" DisableAnimations="true" Hoverable="false" DataTooltip="{x:Null}" Margin="10">
    </lvc:CartesianChart>
</Grid>

Добавление привязки для «шага» разделителя приводит к тому, что график не отображается и пользовательский интерфейс блокируется, но ничего не происходит, и Visual Studio не предоставляет никакой обратной связи с причиной ошибки. Мне интересно, почему это не работает - потому что кажется, что должно. Я установил привязки для других элементов (например, «Заголовок»), используя аналогичный метод, и он работал нормально.

Привязка обновляет значение, потому что я могу отслеживать его продвижение с помощью методов. Это фактическое назначение привязки не работает.

Спасибо ...

Ответы [ 2 ]

0 голосов
/ 12 сентября 2018

Чтобы предотвратить опечатки, вы можете просто использовать оператор nameof, если вы используете как минимум C # 6 (.NET Framework 4.6 или выше). Это будет выглядеть так:

public double LineSeries1XAxisSeparatorStep
{
    get
    {
        return _lineSeries1XAxisSeparatorStep;
    }
    set
    {
        _lineSeries1XAxisSeparatorStep = value;
        OnPropertyChanged(nameof(LineSeries1XAxisSeparatorStep));
    }
}

Или вы можете стать еще проще, если измените метод OnPropertyChanged:

protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = "")
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

Вы найдете CallerMemberName в пространстве имен System.Runtime.CompilerServices (начиная с .NET Framework 4.5)

с помощью этой модификации вы можете упростить вашу собственность до:

public double LineSeries1XAxisSeparatorStep
{
    get { return _lineSeries1XAxisSeparatorStep; }
    set { _lineSeries1XAxisSeparatorStep = value; OnPropertyChanged(); }
}
0 голосов
/ 04 мая 2018

Итак, я выяснил проблему - простая опечатка в следующем коде (имя свойства передано неверно - отсутствует X в LineSeries1 X AxisSeparatorStep) для OnPropertyChanged (исправлено ниже):

public double LineSeries1XAxisSeparatorStep     // Bind the separator for the x-axis to this.
{
    get
    {
        return _lineSeries1XAxisSeparatorStep;
    }
    set
    {
        _lineSeries1XAxisSeparatorStep = value;
        OnPropertyChanged("LineSeries1XAxisSeparatorStep");
    }
}

Программа зависла, потому что я не инициализировал значение для LineSeries1XAxisSeparatorStep, поэтому значение, которое он должен был использовать, было 0, поскольку оно не было нулевым. Инициализация не требуется, если привязка работает правильно.

...