繁体   English   中英

c# 从孩子通知父属性

[英]c# Notify parent property from child

我有以下课程:

public class child
{
   public string product { get; set; }
   public decimal amount { get; set; }
   public decimal price { get; set; }
   public decimal total { get; set; }
}

public class parent
{
   public decimal total { get; set; }
   public BindingList<child> childs { get; set; }
}

现在,在 windows 表单中,我设置以下内容:

var parent_object = new parent();

numericUpDown1.DataBindings.Add("Value", parent_object , "total", true, DataSourceUpdateMode.OnPropertyChanged);
dataGridView1.DataBindings.Add("DataSource", parent_object , "childs", true, DataSourceUpdateMode.OnPropertyChanged);

最后(我不知道该怎么做), parent 的总属性在以下情况下会自动更改:

  1. dataGridView 的某些细节的数量或价格发生了变化。
  2. 一行被添加到 dataGridView。
  3. 从 dataGridView 中删除一行。

谢谢你的帮助。

到目前为止,您的代码看起来很合理,除了在连接所有内容方面缺少一些部分,因此我将提供一些建议。 第一个是简化DataGridView的数据绑定,您需要的只是dataGridView.DataSource = childs 如果您除了通过覆盖MainForm.OnLoad来初始化它之外什么都不做,那么您已经有了一个看起来不错的视图(但它会缺少双向交互)。

预赛

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
    dataGridView.DataSource = childs;
    // Add one or more child items to autogenerate rows.
    childs.Add(new child
    {
        product = "GEARWRENCH Pinch Off Pliers",
        price = 27.10m,
        amount = 1.0m
    });
    childs.Add(new child
    {
        product = "AXEMAX Bungee Cords",
        price = 25.48m,
        amount = 1.0m
    });
    // Format rows
    foreach (DataGridViewColumn column in dataGridView.Columns)
    {
        switch (column.Name)
        {
            case nameof(child.product):
                column.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
                break;
            default:
                column.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
                column.DefaultCellStyle.Format = "F2";
                break;
        }
    }
}
private readonly BindingList<child> childs = new BindingList<child>();
private readonly parent parent_object = new parent();

可绑定属性

为了创建支持双向通信的绑定属性,您需要一种方法来检测和通知属性何时发生变化。 例如,要使parent class 中的total属性可绑定,请执行以下操作:

public class parent : INotifyPropertyChanged
{
    decimal _total = 0;
    public decimal total
    {
        get => _total;
        set
        {
            if (!Equals(_total, value))
            {
                _total = value;
                OnPropertyChanged();
            }
        }
    }
    private void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    public event PropertyChangedEventHandler PropertyChanged;
}

numericUpDown代码中显示的数据绑定现在将响应total的更改。

numericUpDown.DataBindings.Add(
    nameof(numericUpDown.Value),
    parent_object, 
    nameof(parent_object.total), 
    false, 
    DataSourceUpdateMode.OnPropertyChanged);

内部响应变化

通过使用上面的示例以相同的方式使child class 中的所有属性可绑定后,请考虑采用在内部处理某些更改的方法,在这种情况下,您将禁止触发属性更改通知。

public class child : INotifyPropertyChanged
{
    private void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        switch (propertyName)
        {
            case nameof(price):
            case nameof(amount):
                // Perform an internal calculation.
                recalcTotal();
                break;
            default:
                // Notify subscribers of important changes like product and total.
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
                break;
        }
    }
    private void recalcTotal()
    {
        total = price * amount;
    }
    ...
}

连接parent class 中的total属性。

现在唯一缺少的是有一种方法可以告诉parent_object所有行都需要一个新的全局总计。 好消息是绑定已经在前面的步骤中就位。 要检测对childs任何更改,无论是添加新行还是编辑总计,请订阅子集合的ListChanged事件,方法是将其设为OnLoad中的第一行(在添加任何项目之前)。

childs.ListChanged += parent_object.onChildrenChanged;

这是需要在parent_object class 中实现的方法。 像这样的东西:

internal void onChildrenChanged(object sender, ListChangedEventArgs e)
{
    var tmpTotal = 0m;
    foreach (var child in (IList<child>)sender)
    {
        tmpTotal += child.total;
    }
    total = tmpTotal;
}

准备测试

如果您实施这些步骤,您将拥有一个功能齐全的链接视图,您可以在其中添加、删除和修改child记录。

功能结合

希望这能提供一些关于所有拼图如何组合在一起的整体见解。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM