简体   繁体   中英

WPF DataGrid refresh cell when calculated column changes

Trying to make an interactive grid that updates calculated columns as the user types in values. Ideally as rows are added and existing rows are changed, the calculated read only cells would update automatically minimally as the cursor leaves the modified cell. Ideally while the user is typing if performance degradation is not an issue.

With an Entity Data Model such as this:

public class CalculatorContext : DbContext
{
    public CalculatorContext() : base("name=CalculatorContext") { }

    public virtual DbSet<MyEntity> MyEntities { get; set; }
    public virtual DbSet<Calculation> Calculations { get; set; }
}

public class MyEntity
{
    public MyEntity()
    {
        Calculations = new ObservableCollection<Calculation>();
    }

    [Key]
    public int EntityId { get; set; }
    public string Name { get; set; }

    public virtual ObservableCollection<Calculation> Calculations { get; set; }
}

public class Calculation
{
    [Key]
    public int CalcId { get; set; }
    public int EntityId { get; set; }

    public int VariableX { get; set; }
    public int VariableY { get; set; }

    [NotMapped]
    public int Sum { get { return VariableX + VariableY; } }
    [NotMapped]
    public int Product { get { return VariableX * VariableY; } }

    public virtual MyEntity ParentEntity { get; set; }
}

The following grid only refreshes the Sum and Product columns when sorted by that column (or saved and refreshed):

    <DataGrid x:Name="calculationsDataGrid" AutoGenerateColumns="False" EnableRowVirtualization="True" ItemsSource="{Binding}" 
              Margin="30,30,30,70" RowDetailsVisibilityMode="VisibleWhenSelected" CellEditEnding="calculationsDataGrid_CellEditEnding" >
        <DataGrid.Columns>
            <DataGridTextColumn x:Name="variableXColumn" Binding="{Binding VariableX}" Header="X" Width="SizeToHeader"/>
            <DataGridTextColumn x:Name="variableYColumn" Binding="{Binding VariableY}" Header="Y" Width="SizeToHeader"/>
            <DataGridTextColumn x:Name="sumColumn" Binding="{Binding Sum}" Header="Sum" IsReadOnly="True"/>
            <DataGridTextColumn x:Name="productColumn" Binding="{Binding Product}" Header="Product" IsReadOnly="True"/>
        </DataGrid.Columns>
    </DataGrid>

Calling DataGrid.Items.Refresh() from the CellEditEnding event simply results in an "InvalidOperationException: 'Refresh' is not allowed during an AddNew or EditItem transaction." I've tried adding some logic to the RowEditEnding, SourceUpdated and SelectedCellsChanged events but am not sure what method to call in order to refresh the screen using the new calculation (add or multiply the variables). Really only the 2 read only cells on the same row need to be refreshed.

As you can see I am using an ObservableCollection. Do I need to implment INotifiedChanges or something similar? If so how?

Yes, to notify databound controls of property changes dynamically you will want to implement iNotifyPropertyChanged on the elements within your collection. Then on the properties that make up your computed property changes you can also notify that the computed property has changed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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