需要来自Guru的WPF数据绑定帮助

时间:2012-11-29 22:58:00

标签: c# wpf data-binding refactoring

我有一个C#类,它同时包含一个ObservableCollection和一个包含ObservableCollections对象的数组。对象数组中的值是根据第一个基本集合中的值计算的。 BindableBase只实现了INotifyPropertyChanged。

我已尽可能简化了我的实施。

RawDS拥有一个RawData的ObservableCollection,它还包含10个CalcDS对象的数组,这些对象是CalcData的ObservableCollections。

所有这一切都很有效。我有工作线程,它累积计算结果的输入数据并用计算数据填充数组。我的问题是将所有这些数据绑定到WPF中的单个图表和网格。我已经研究,阅读并尝试了我能找到的所有内容,但似乎无法使数据绑定与RawData和CalcData对象中的属性一起使用。我认为问题源于这样一个事实,即我绑定的是一个不是ObservableCollection的对象,而是一个在其中有ObservableCollections的对象。所以我的问题是两个方面。

  1. 有没有办法做这种数据绑定?我一直在将DataChart和DataGrid的DataContext设置为基础对象RawDS,并尝试将所有内容与DataBindings Source和Path Properties结合起来。没有快乐!

  2. 如果没有,那么重构数据类的好方法就是在没有大量维护属性的情况下工作的信息。 CalcData类现在有14个属性(10次),我能想到的一切最终都是一个巨大的单片类。这将是一场维护噩梦。

  3. 提前感谢您的帮助。

    public class CalcData : BindableBase
    {
        private Single _plotValue1;
    
        public Single PlotValue1
        {
            get { return _plotValue1; }
            set { SetProperty(ref _plotValue1, value); }
        }
    }
    
    public class CalcDS : ObservableCollection<CalcData>
    {
        public CalcDS()
        {
            var random = new Random();
            for (var i = 0; i < 25; i++)
            {
                var cd = new CalcData
                {
                    PlotValue1 = random.Next(10, 50)
                };
                Add(cd);
            }
        }
    }
    
    public class RawData : BindableBase
    {
        private DateTime _xDateTime;
        private Single _plotValue;
    
        public DateTime XDateTime
        {
            get { return _xDateTime; }
            set { SetProperty(ref _xDateTime, value); }
        }
    
        public Single PlotValue
        {
            get { return _plotValue; }
            set { SetProperty(ref _plotValue, value); }
        }
    }
    
    public class RawDS : BindableBase
    {
        private readonly ObservableCollection<RawData> _rawMDP = new ObservableCollection<RawData>();
        private readonly CalcDS [] _calcDsDataAry = new CalcDS [10];
    
        // Initialize things and get the worker thread going.
        public RawDS()
        {
            var random = new Random();
            var times = new DateTime(2012, 1, 1);
            for (var i = 0; i < 25; i++)
            {
                var time = new TimeSpan(0, random.Next(0, 5), 0);
                times = times.Add(time);
                var rd = new RawData
                {
                    XDateTime = times,
                    PlotValue = random.Next(10, 50)
                };
                _rawMDP.Add(rd);
            }
    
            // Create 10 CalcDS objests numbered 0 to 9
            for (var cnt = 0; cnt < 10; cnt++)
                _calcDsDataAry[cnt] = new CalcDS();
        }
    
        public ObservableCollection<RawData> RawMDP
        { get { return _rawMDP; } }
    
        public CalcDS CalcDsData01
        { get { return _calcDsDataAry[0]; } }
    
        public CalcDS CalcDsData02
        { get { return _calcDsDataAry[1]; } }
    
        public CalcDS CalcDsData03
        { get { return _calcDsDataAry[2]; } }
    
        public CalcDS CalcDsData04
        { get { return _calcDsDataAry[3]; } }
    
        public CalcDS CalcDsData05
        { get { return _calcDsDataAry[4]; } }
    
        public CalcDS CalcDsData06
        { get { return _calcDsDataAry[5]; } }
    
        public CalcDS CalcDsData07
        { get { return _calcDsDataAry[6]; } }
    
        public CalcDS CalcDsData08
        { get { return _calcDsDataAry[7]; } }
    
        public CalcDS CalcDsData09
        { get { return _calcDsDataAry[8]; } }
    
        public CalcDS CalcDsData10
        { get { return _calcDsDataAry[9]; } }
    }
    

2 个答案:

答案 0 :(得分:0)

我相信可行的方法是将数组包装在一个自定义容器中,该容器实现INotifyCollectionChanged然后订阅每个项目的PropertyChanged事件(当添加到集合中时,并在删除/处置时取消订阅)和举起CollectionChanged事件。

如果没有其他人能够很好地解决这个问题,我可能有时间看看它。

答案 1 :(得分:0)

问题是数组没有实现INotifyPropertyChanged,因此UI不知道数据是否在变化。 Steve Py对包装它有一个好主意。

如果你可以将它从数组更改为ObservableCollection会使事情变得更容易。