Заставить детей одного класса общаться друг с другом - PullRequest
0 голосов
/ 18 июня 2020

У меня проблемы с ViewModel моего кода шаблона MVVM.

У меня есть набор измерений и набор правил для оценки измерений, хранящихся в классах Rule и Measurement. В моем основном классе MyClass я сохраняю свои правила и измерения затем в ObservableCollections (O C) (и подключаюсь к DataGrid).

Для всех n правил я создаю n CollcetionOfEvaluators за один O C и передаю соответствующее правило и все измерения для каждого отдельного. В каждой CollectionOfEvaulators я создаю для одного правила и m измерений m оценщиков в O C.

Оценщики берут одно Правило и одно Измерение и возвращают bool, если соответствующее Измерение или нет. передает соответствующее правило.

Затем у меня есть ListView, который отображает для каждого правила DataGrid, который отображается для каждого измерения, если оно прошло правило.

Моя проблема состоит в том, чтобы запустить класс Evaluator метод OnPropertyChanged, если я изменю свойства одного из измерений в MyClass. Как я могу передать информацию в основном от одного ребенка ребенку другого ребенка? Когда я играю с DataGrid оценщиков, например, щелкаю заголовок, чтобы переставить его, это работает. Итак, я предполагаю, что проблема заключается в коде c#, а не в xaml. Так что я оставлю это на этот раз. Все привязки: Mode = TwoWay (кроме bool, поскольку у него нет установщика) и UpdateSourceTrigger = PropertyChanged.

Я попытался набросать проблему: enter image description here

Это мой код:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Text;

namespace demo
{
    public class MyClass : INotifyPropertyChanged
    {
        public class Measurement : INotifyPropertyChanged
        {
            private double? myValue1;

            public double? MyValue1
            {
                get { return myValue1; }
                set
                {
                    myValue1 = value;
                    OnPropertyChanged("MyValue1");
                }
            }

            private double? myValue2;

            public double? MyValue2
            {
                get { return myValue2; }
                set
                {
                    myValue2 = value;
                    OnPropertyChanged("MyValue2");
                }
            }

            public event PropertyChangedEventHandler PropertyChanged;

            private void OnPropertyChanged(string propertyName)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }

        }

        public class EvaluationRule
        {
            public EvaluationRule(double Value1Min, double Value2Min)
            {
                this.Value1Min = Value1Min;
                this.Value2Min = Value2Min;
            }

            public double Value1Min;
            public double Value2Min;

        }

        public class Evaluator : INotifyPropertyChanged
        {
            public Evaluator(Measurement Measurement, EvaluationRule Rule)
            {
                this.Rule = Rule;
                this.Measurement = Measurement;
            }

            public EvaluationRule Rule;

            private Measurement measurement;
            public Measurement Measurement
            {
                get { return measurement; }
                set
                {
                    measurement = value;
                    OnPropertyChanged("Measurement");
                }
            }

            public bool IsApproved
            {
                get
                {
                    if (measurement.MyValue1 > Rule.Value1Min
                        && measurement.MyValue2 > Rule.Value2Min)
                    {
                        return true;
                    }
                    return false;
                }
            }

            public event PropertyChangedEventHandler PropertyChanged;

            private void OnPropertyChanged(string propertyName)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public class CollectionOfEvaluators : INotifyPropertyChanged
        {
            public CollectionOfEvaluators(EvaluationRule Rule, ObservableCollection<Measurement> Measurements)
            {
                this.Rule = Rule;
                this.Measurements = Measurements;

                var Evaluators = new ObservableCollection<Evaluator>();
                foreach (var _measurement in Measurements)
                {
                    var _evaluator = new Evaluator(_measurement, this.Rule);
                    Evaluators.Add(_evaluator);
                }
            }

            public EvaluationRule Rule;

            private ObservableCollection<Measurement> measurements;

            public ObservableCollection<Measurement> Measurements
            {
                get { return measurements; }
                set
                {
                    measurements = value;
                    OnPropertyChanged("Measurements");
                }
            }

            private ObservableCollection<Evaluator> evaluators;

            public ObservableCollection<Evaluator> Evaluators
            {
                get { return evaluators; }
                set
                {
                    evaluators = value;
                    OnPropertyChanged("Evaluators");
                }
            }

            public event PropertyChangedEventHandler PropertyChanged;

            private void OnPropertyChanged(string propertyName)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        private ObservableCollection<Measurement> measurements;

        public ObservableCollection<Measurement> Measurements
        {
            get { return measurements; }
            set
            {
                measurements = value;
                OnPropertyChanged("Measurements");
            }
        }

        private ObservableCollection<EvaluationRule> rules;

        public ObservableCollection<EvaluationRule> Rules
        {
            get { return rules; }
            set
            {
                rules = value;
                GetCollection();
            }
        }

        private ObservableCollection<CollectionOfEvaluators> collection;

        public ObservableCollection<CollectionOfEvaluators> Collection
        {
            get { return collection; }
            set
            {
                collection = value;
                OnPropertyChanged("Collection");
            }
        }

        public void GetCollection()
        {
            var Collection = new ObservableCollection<CollectionOfEvaluators>();
            foreach (var _rule in rules)
            {
                var _collection = new CollectionOfEvaluators(_rule, Measurements);
                Collection.Add(_collection);
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

1 Ответ

1 голос
/ 18 июня 2020

Вы должны делегировать мероприятие. Evaluator должен прослушивать событие PropertyChanged своего агрегированного Measurement. Затем обработчик этого события может вызвать событие Evaluator.PropertyChanged в ответ:

public class Evaluator : INotifyPropertyChanged
{
  public Evaluator(Measurement measurement, EvaluationRule rule)
  {
    this.Rule = rule;
    this.Measurement = measurement;

    this.Measurement.PropertyChanged += OnMeasurementPropertyChanged;
  }

  public void OnMeasurementPropertyChanged(object sender, PropertyChangedEventAgrs e)
  {
    OnPropertyChanged(nameof(this.Measurement));
  }

  private Measurement measurement;
  public Measurement Measurement
  {
    get  => this.measurement
    set
    {
      this.measurement = value;
      OnPropertyChanged(nameof(this.Measurement));
    }
  }

  public event PropertyChangedEventHandler PropertyChanged;
  private void OnPropertyChanged(string propertyName)
  {
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
  }
}

Обратите внимание, что вы получили орфографическую ошибку при названии вашего класса. Это Я а гарантия - вы пропустили «а». Также имена параметров всегда должны быть в нижнем регистре.

...