首页 > 解决方案 > WPF 绑定找不到数据项

问题描述

我对数据绑定和 MVVM 的概念很陌生,所以过去几天我一直在尝试。基本上,我想要做的是使用 LiveCharts 库,我想从上传的 CSV 文件中同时显示多个图表。

到目前为止我做得很好,但现在我正在编写代码,以便如果我想在一个图表中增加 X 轴的单位,我可以与其他图表同时这样做。(为了上下文,x轴以时间戳为单位,不同的图表应该有相同的时间戳,但同一时间戳下的ID不同,值也不同)

我的 UI 中的代码是这样的(省略了一些我认为不必要的代码):

<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");
                }
            }
        }

尽管对于最小值和最大值,我目前都收到此错误:

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')

我会很感激朝着正确的方向轻推,因为所有这些对我来说都是全新的。绑定有什么我错过的吗?我认为通过将它们放在一个类中,我将能够从 UI 访问它们。为什么我可以查看 SeriesViews,但不能查看同一类的 Xmin 和 Xmax?

标签: wpfdata-binding

解决方案


问题肯定是,Grid您的ItemsControl. 将更改AncestorTypeItemsControl,您将获得绑定工作。

<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>

推荐阅读