Привязка WPF не может найти элемент данных - PullRequest
0 голосов
/ 27 апреля 2020

Я совершенно новичок в концепции привязки данных и MVVM, поэтому я пробовал это в последние пару дней. По сути, я пытаюсь использовать библиотеку LiveCharts, я хочу отображать несколько графиков одновременно из загруженного файла CSV.

Пока у меня все хорошо, но сейчас я пишу код так что, если я хочу увеличить единицы измерения по оси X на одном графике, я могу сделать это одновременно с другими. (Для контекста, ось x находится в единице метки времени, и разные диаграммы должны иметь одну и ту же метку времени, но разные идентификаторы и разные значения при одной и той же метке времени)

Код в моем пользовательском интерфейсе выглядит следующим образом ( пропущен некоторый код, который я считаю ненужным):

<ItemsControl ItemsSource="{Binding SeriesViews}" VerticalAlignment="Top">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Border Background="White">
                     <lvc:CartesianChart Series="{Binding}" Pan="X">
                        <lvc:CartesianChart.AxisX>
                            <lvc:Axis RangeChanged="Axis_RangeChanged" 
                                      MinValue="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Grid}}, Path=DataContext.Xmin}" 
                                      MaxValue="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Grid}}, Path=DataContext.Xmax}"
                                      Separator="{x:Static lvc:DefaultAxes.CleanSeparator}">
                            </lvc:Axis>
                        </lvc:CartesianChart.AxisX>
                    </lvc:CartesianChart>
                </Border>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

Другой конец выглядит так:

    public GraphData gd;
    public Graphs()
    {
        InitializeComponent();
    }

    public void GenerateCSVList(string csvPath)
    {
        using (var reader = new StreamReader(csvPath))
        using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
        {
            ExcelRecords = csv.GetRecords<Emotions>().ToList();
        }

        gd = new GraphData();
        gd.Xmin = 0;
        gd.Xmax = 5;
        gd.SeriesViews = ReturnChart();
        this.DataContext = gd;
    }

    public ObservableCollection<SeriesCollection> ReturnChart()
        {
            ObservableCollection<SeriesCollection> ChartCollection = new ObservableCollection<SeriesCollection>();
            //Draw charts here
            return ChartCollection
        }

    public class GraphData : INotifyPropertyChanged
        {
            public ObservableCollection<SeriesCollection> SeriesViews { get; set; }
            private double _xmin;
            private double _xmax;

            public event PropertyChangedEventHandler PropertyChanged;
            protected virtual void OnPropertyChanged(string propertyName = null)
            {
                if (PropertyChanged != null)
                    PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
            public double Xmin
            {
                get { return _xmin; }
                set
                {
                    _xmin = value;
                    OnPropertyChanged("Xmin");
                }
            }
            public double Xmax
            {
                get { return _xmax; }
                set
                {
                    _xmax = value;
                    OnPropertyChanged("Xmax");
                }
            }
        }

В настоящее время я получаю эту ошибку, как для min, так и для max значения:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.Grid', AncestorLevel='1''. BindingExpression:Path=DataContext.Xmax; DataItem=null; target element is 'Axis' (Name=''); target property is 'MaxValue' (type 'Double')

Я был бы признателен за толчок в правильном направлении, так как все это довольно ново для меня. Что-то я пропустил с привязкой? Я думал, поместив их в один класс, я смогу получить к ним доступ из пользовательского интерфейса. Почему я могу просматривать SeriesViews, но не Xmin и Xmax из одного класса?

1 Ответ

0 голосов
/ 27 апреля 2020

Проблема определенно в том, что у вас нет Grid в качестве родительского контейнера для вашего ItemsControl. Измените AncestorType на ItemsControl, и вы получите работу переплета.

<lvc:Axis RangeChanged="Axis_RangeChanged" 
          MinValue="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}, Path=DataContext.Xmin}" 
          MaxValue="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}, Path=DataContext.Xmax}"
          Separator="{x:Static lvc:DefaultAxes.CleanSeparator}">
</lvc:Axis>
...