Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何更新子类中的计算值_C#_Wpf_Mvvm_Data Binding - Fatal编程技术网

C# 如何更新子类中的计算值

C# 如何更新子类中的计算值,c#,wpf,mvvm,data-binding,C#,Wpf,Mvvm,Data Binding,正如标题所示,我希望更新子类中的计算值。在我的WPF页面中,我将FPBViewModel的参数集合作为DataGrid的ItemSource。加热气流只是最小气流和风扇气流的总和。在数据网格中更改MinAirflow或fanarflow参数值时,使HeatingAirflow参数值自动更新的最佳方法是什么 我已经考虑过使用计算器方法,但是当我最终创建一个新的ParameterViewModel并替换Parameters集合中的“旧”vm时,实现会觉得很笨拙。另外,FPBModel类中有许多计算值

正如标题所示,我希望更新子类中的计算值。在我的WPF页面中,我将FPBViewModel的
参数
集合作为DataGrid的ItemSource。
加热气流
只是
最小气流
风扇气流
的总和。在数据网格中更改
MinAirflow
fanarflow
参数值时,使
HeatingAirflow
参数值自动更新的最佳方法是什么

我已经考虑过使用计算器方法,但是当我最终创建一个新的
ParameterViewModel
并替换
Parameters
集合中的“旧”vm时,实现会觉得很笨拙。另外,FPBModel类中有许多计算值供参考,这只是最简单的示例。理想情况下,有一种方法可以使用PropertyChanged事件,但由于某些原因,我无法在嵌套类中找到它

FPB模型

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);
    }
}
参数视图模型

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

您看过在ViewModel中使用命令吗?这是我想到的第一件事。如果你不能利用命令,一个转换器可能会工作。当UI导致对模型进行级联更改时,我会尝试将该机制保留在VM或视图中。我同意增加一个计算器会觉得笨重。但一次性命令或转换器通常更为友好。在贡献属性上处理
属性更改
,并在其值更改时更新
HeatingAirflow.Value
(或仅替换
HeatingAirflow
)。当然,在替换其他任何一个参数ViewModel时也要更新HeatingAirflow,并注意取消处理事件(或使用弱引用),以免混淆垃圾收集器。这是做这件事的标准方法。命令或值转换器将是一种非常奇怪的方式。值转换器在viewmodel中不起作用,存在由视图执行的命令。父viewmodel应该负责所有这些。我发现将子视图模型之间的关系作为父视图模型的唯一责任是一条非常好的规则。只要让孩子们引发事件,这样家长们就可以在需要的时候采取行动。你看过在ViewModel中使用命令吗?这是我想到的第一件事。如果你不能利用命令,一个转换器可能会工作。当UI导致对模型进行级联更改时,我会尝试将该机制保留在VM或视图中。我同意增加一个计算器会觉得笨重。但一次性命令或转换器通常更为友好。在贡献属性上处理
属性更改
,并在其值更改时更新
HeatingAirflow.Value
(或仅替换
HeatingAirflow
)。当然,在替换其他任何一个参数ViewModel时也要更新HeatingAirflow,并注意取消处理事件(或使用弱引用),以免混淆垃圾收集器。这是做这件事的标准方法。命令或值转换器将是一种非常奇怪的方式。值转换器在viewmodel中不起作用,存在由视图执行的命令。父viewmodel应该负责所有这些。我发现将子视图模型之间的关系作为父视图模型的唯一责任是一条非常好的规则。只要让孩子们发起活动,家长们就可以在需要的时候采取行动。
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;
    }
}