1

単一の ObservableCollection と、ObservableCollection であるオブジェクトを保持する配列の両方を保持する C# クラスがあります。オブジェクトの配列の値は、最初の基本コレクションの値から計算されます。BindableBase は INotifyPropertyChanged を実装するだけです。

以下で実装を可能な限り単純化しました。

RawDS は、RawData の ObservableCollection を保持します。また、CalcData の ObservableCollection である 10 個の CalcDS オブジェクトの配列も保持します。

これはすべてうまくいきます。結果を計算し、計算されたデータで配列を埋める受信データを蓄積するワーカー スレッドがあります。私の問題は、これらすべてを WPF 内の単一のチャートとグリッドにバインドするデータです。私は見つけたすべてのものを調査し、読んで試しましたが、RawData および CalcData オブジェクトのプロパティでデータ バインディングを機能させることができないようです。この問題は、ObservableCollection ではなく ObservableCollections を含むオブジェクトにバインドしていることが原因であると考えています。だから私の質問は、何を2倍にするかです。

  1. この種のデータバインディングを行う方法はありますか? DataChart と DataGrid の DataContext を基本オブジェクト RawDS に設定し、すべてを DataBindings Source プロパティと Path プロパティに結合しようとしています。喜びはありません!

  2. そうでない場合、以下のデータ クラスをリファクタリングする良い方法は何か、維持するプロパティが爆発的に増加することなく機能するものを教えてください。CalcData クラスには 14 個のプロパティ (10 倍) があり、考えられるすべてが 1 つの大きなモノリシック クラスになります。これはメンテナンスの悪夢です。

助けてくれてありがとう。

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]; } }
}
4

2 に答える 2

0

うまくいくかもしれないのは、INotifyCollectionChanged各アイテムのPropertyChangedイベントを実装してサブスクライブし(コレクションに追加された場合、削除/破棄された場合はサブスクライブ解除)、CollectionChangedイベントを発生させるカスタムコンテナに配列をラップすることだと思います。

他の誰も解決策をうまく突き刺さないのであれば、私はそれを見る時間があるかもしれません。

于 2012-11-30T00:02:28.073 に答える
0

問題は、配列が INotifyPropertyChanged を実装していないため、UI はデータが変化していることを認識できないことです。Steve Py はそれをラップする良いアイデアを持っています。

配列から ObservableCollection に変更できれば、作業が簡単になります。

于 2012-11-30T02:05:29.497 に答える