How to update calculated values in subclasses

2019-07-26 14:54发布

As the title suggests I am looking to update calculated values in a subclass. I have the FPBViewModel's Parameters collection as a DataGrid's ItemSource in my WPF page. The HeatingAirflow is just the sum of the MinAirflow and the FanAirflow. What is the best way to make the HeatingAirflow parameter's value automatically update when either the MinAirflow or FanAirflow parameter's value is changed in the DataGrid?

I have looked into using a calculator method, but the implementation feels clunky as I end up creating a new ParameterViewModel and replacing the "old" vm in the Parameters collection. Also for reference there are many calculated values in the FPBModel class, this is just the easiest example. Ideally there would be way to use the PropertyChanged event, but for some reason I haven't been able to get there in the nested classes.

FPBModel

public class EngineFPB : EngineMechanicalEquipment
{
    private Parameter _minAirflow;
    private Parameter _fanAirflow;
    private Parameter _heatingAirflow;

    public Parameter MinAirflow
    {
        get { return _minAirflow; }
        set { _minAirflow = value; }
    }

    public eParameter FanAirflow
    {
        get { return _fanAirflow; }
        set { _fanAirflow = value; }
    }

    public Parameter HeatingAirflow
    {
        get => _heatingAirflow;
        //set => _heatingAirflow = _minAirflow + _fanAirflow;
    }

    public FPB(Element element)
    {
        UTILUnitConverter UC = new UTILUnitConverter();
        double min = element.min;
        double fan = element.fan;

        _minAirflow = new EngineParameter("Min Airflow", min, false);
        _fanAirflow = new EngineParameter("Fan Airflow", fan, false);

        _heatingAirflow = new EngineParameter("Heating Airflow", 0, false);
        CalculateFields();
    }

    public void CalculateFields()
    { 
        double heatingAirflow = Convert.ToDouble(_minAirflow.Value) + Convert.ToDouble(_fanAirflow.Value);
        _heatingAirflow.Value = heatingAirflow;
    }
}

FPBViewModel

public class FPBViewModel : ViewModelBase
{
    private ObservableCollection<ParameterViewModel> _parameters = new ObservableCollection<ParameterViewModel>();
    public ObservableCollection<ParameterViewModel> Parameters
    {
        get => _parameters;
        set
        {
            _parameters = value;
            RaiseProperty(nameof(Parameters));
        }
    }

    private ParameterViewModel _minAirflow;
    public ParameterViewModel MinAirflow
    {
        get => _minAirflow;
        set
        {
            _minAirflow = value;
            RaiseProperty(nameof(MinAirflow));
        }
    }

    private ParameterViewModel _fanAirflow;
    public ParameterViewModel FanAirflow
    {
        get => _fanAirflow;
        set
        {
            _fanAirflow = value;
            RaiseProperty(nameof(FanAirflow));
        }
    }

    private ParameterViewModel _heatingAirflow;
    public ParameterViewModel HeatingAirflow
    {
        get => _heatingAirflow;
        set
        {
            _heatingAirflow = value;
            RaiseProperty(nameof(HeatingAirflow));
        }
    }

    public FPBViewModel(EngineFPB fpb)
    {
        _minAirflow = new ParameterViewModel(fpb.MinAirflow, false);
        _fanAirflow = new ParameterViewModel(fpb.FanAirflow, false);
        _heatingAirflow = new ParameterViewModel(fpb.HeatingAirflow, true);

        _parameters.Add(MinAirflow);
        _parameters.Add(FanAirflow);
        _parameters.Add(HeatingAirflow);
    }
}

Parameter Class

public class EngineParameter
{
    private string _name;
    private object _value;
    private bool _isReadOnly;

    public string Name
    {
        get => _name;
        set => _name = value;
    }
    public object Value
    {
        get => _value;
        set => _value = value;
    }

    public bool IsReadOnly
    {
        get => _isReadOnly;
        set => _isReadOnly = value;
    }

    public EngineParameter(string name, object value, bool isReadOnly) 
    {
        _name = name;
        _value = value;
        _isReadOnly = isReadOnly;
    }
}

ParameterViewModel

public class ParameterViewModel : ViewModelBase
{
    private Parameter _parameter;
    private bool _isReadOnly;

    public bool IsReadOnly
    {
        get => _isReadOnly;
        set => _isReadOnly = value;
    }

    public string Name
    {
        get => _parameter.Name;
    }

    public object Value
    {
        get => _parameter.Value;
        set
        {
            if (!_isReadOnly)
            {
                _parameter.Value = value;
                RaiseProperty(nameof(Value));
            }
        }
    }

    public ParameterViewModel(Parameter parameter, bool isReadOnly)
    {
        _parameter = parameter;
        _isReadOnly = isReadOnly;
    }
}

0条回答
登录 后发表回答