0
Follow
2
View

Datagridview Dynamic cell calculation

anhui_my 注册会员
2023-01-24 21:40

This isn't too difficult using your existing code: First of all, use the name of the edited column in if/else if statements to filter which conversion should take place, so that changing the VAT column doesn't get overwritten by the preVAT column. Then, use the opposite algebraic expression of the one you already have written to convert the postVAT price back to the preVAT

Here is what it will look like:

Filho.CurrentRow.Cells["ArtigoPai"].Value = tb_CodigoArtigo.Text;
dgv_Filho.CurrentRow.Cells["Descricao_Pai"].Value = tb_Descricao.Text + " " + Medida_1 + Medida_2;
dgv_Filho.CurrentRow.Cells["CodigoArtigoFilho"].Value = tb_CodigoArtigo.Text + Medida_1 + Medida_2;
decimal PrecoFilho = Convert.ToDecimal(dgv_Filho.CurrentRow.Cells["PrecoFilhoSemIva"].Value);
decimal PrecoFilhoComIva = Convert.ToDecimal(dgv_Filho.CurrentRow.Cells["PrecoFilhoComIva"].Value);
if (dgv_Filho.Columns[e.ColumnIndex].Name == "PrecoFilhoSemIva")
{
    PrecoFilhoComIva = PrecoFilho * (Iva / 100) + PrecoFilho;
    dgv_Filho.CurrentRow.Cells["PrecoFilhoComIva"].Value = PrecoFilhoComIva;
}
else if (dgv_Filho.Columns[e.ColumnIndex].Name == "PrecoFilhoComIva")
{
    decimal PrecoFilhoSemIva = PrecoFilhoComIva - (PrecoFilhoComIva / (1 + (Iva / 100)) * (Iva / 100));
    dgv_Filho.CurrentRow.Cells["PrecoFilhoSemIva"].Value = PrecoFilhoSemIva;
}

Using this code, editing the preVAT value will automatically update the postVAT value accordingly, and editing the postVAT value will automatically update the preVAT value accordingly

ddr520520 注册会员
2023-01-24 21:40

Rather than interact with the DataGridView directly (which can be complex) you could instead make a class that implements INotifyPropertyChanged and keeps all of its internal calculations up-to-date at all times (which is easier). Here is a simplified version of such a class that responds to changes of Descricao, Medida and PrecoFilhoSemIva.


class Articulo : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    string _descricao = string.Empty;
    public string Descricao
    {
        get => _descricao;
        set
        {
            if (!Equals(_descricao, value))
            {
                _descricao = value;
                OnPropertyChanged();
            }
        }
    }
    public string Descricao_Pai => $"{Descricao} {Medida_1}@{_precoFilhoSemIva.ToString("F2")}";
    public decimal PrecoFilhoComIva => _precoFilhoSemIva * (1.0m + MainForm.Iva);

    decimal _medida = 0;
    public decimal Medida
    {
        get => _medida;
        set
        {
            if (!Equals(_medida, value))
            {
                _medida = value;
                OnPropertyChanged();
            }
        }
    }

    decimal _precoFilhoSemIva = 0;
    public decimal PrecoFilhoSemIva
    {
        get => _precoFilhoSemIva;
        set
        {
            if (!Equals(_precoFilhoSemIva, value))
            {
                _precoFilhoSemIva = value;
                OnPropertyChanged();
            }
        }
    }
    string _codigoArtigo = System.Guid.NewGuid().ToString().Substring(0, 10).ToUpper();
    public string CodigoArtigo
    {
        get => _codigoArtigo;
        set
        {
            if (!Equals(_codigoArtigo, value))
            {
                _codigoArtigo = value;
                OnPropertyChanged();
            }
        }
    }
}

Instances of this class are placed in a BindingList which is assigned to the DataSource property of Filho and caused the DGV to update whenever the Refresh method is called.


The only interaction that should be necessary with the DGV is to initialize the columns and bindings properly in the MainForm override for the Load event. This is also where we bind the combo box to a static value for Iva that can be used by the calculation for the row items.

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
    initDataGridView();
    initComboBox();
}
private void initDataGridView()
{
    dgv_Filho.DataSource = DataSource;
    DataSource.ListChanged += (sender, e) =>
    {
        if (e.ListChangedType == ListChangedType.ItemChanged)
        {
            dgv_Filho.Refresh();
        }
    };
    // Add one or more items to autogenerate the columns.
    Random randomPriceGen = new Random(1);
    for (int i = 1; i <= 3; i++)
    {
        var preco = i == 1 ? 1.0m : (decimal)randomPriceGen.NextDouble() * 100;
        DataSource.Add(new Articulo
        {
            Descricao = $"Articulo {(char)('A' + (i - 1))}",
            Medida = i,
            PrecoFilhoSemIva = preco,
        });
    }
    // Do a little column formatting
    foreach (DataGridViewColumn column in dgv_Filho.Columns)
    {
        switch (column.Name)
        {
            case nameof(Articulo.Descricao):
                column.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
                column.MinimumWidth = 120;
                break;
            case nameof(Articulo.Medida):
            case nameof(Articulo.PrecoFilhoSemIva):
            case nameof(Articulo.PrecoFilhoComIva):
                column.DefaultCellStyle.Format = "F2";
                column.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
                break;
            default:
                column.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
                break;
        }
    }
}
private void initComboBox()
{
    cb_Iva.SelectedIndex = 0;
    cb_Iva.SelectedIndexChanged += onIvaSelected;
    cb_Iva.KeyDown += (sender, e) =>
    {
        if( e.KeyData == Keys.Enter)
        {
            e.Handled = e.SuppressKeyPress = true;
        }
        onIvaSelected(sender, e);
    };
    onIvaSelected(cb_Iva, EventArgs.Empty);

    void onIvaSelected(object sender, EventArgs e)
    {
        if (decimal.TryParse(cb_Iva.Text.Replace("%", string.Empty), out decimal iva))
        {
            Iva = iva / 100m;
            dgv_Filho.Refresh();
            cb_Iva.BackColor = SystemColors.Window;
        }
        else cb_Iva.BackColor = Color.LightSalmon;
    }
}

About the Author

Question Info

Publish Time
2023-01-24 21:40
Update Time
2023-01-24 21:40