visual tiempo modificar fila eliminar ejecucion editar despues desde datos dato como celda automaticamente agregar actualizar c# wpf mvvm datagrid mvvm-light

tiempo - eliminar datos de un datagridview c#



No se puede actualizar Datagrid y guardar cambios en la base de datos (2)

Para que la columna "total" en DataGrid se actualice, la clase Product debe implementar la interfaz INotifyPropertyChanged y generar el evento PropertyChanged para la propiedad Total :

private double _total; public double Total { get { return _total; } set { _total = value; OnPropertyChanged("Total"); } }

Y para que pueda guardar el valor en la base de datos, necesita asignar la propiedad Total a una columna en su tabla de base de datos, tal como lo hizo (afortunadamente) con las otras columnas.

Tengo una cuadrícula de datos, una ObservableCollection de tipos de productos en un ViewModel y una implementación de EventToCommand como se muestra a continuación. Me gustaría actualizar la Columna total del producto de Columna de cantidad y costo y guardar los cambios sin usar el código malvado detrás o Windows Forms DataGridView. ¿Cómo puedo conseguir esto? Cuadrícula de datos:

<DataGrid x:Name="dataGrid" Margin="5,5,10,5" AutoGenerateColumns="False" HorizontalAlignment="Stretch" ItemsSource="{Binding ProductList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Stretch" Height="566" > <i:Interaction.Triggers> <i:EventTrigger EventName="CellEditEnding" SourceObject="{Binding ElementName=Control}"> <cmd:EventToCommand Command="{Binding EndEdit}" PassEventArgsToCommand="True"/> </i:EventTrigger> </i:Interaction.Triggers> <DataGrid.Columns> <DataGridTextColumn x:Name="Id" Binding="{Binding Path=Id, Mode=TwoWay}" Header="Id"/> <DataGridTextColumn x:Name="name" Binding="{Binding Path=Name, Mode=TwoWay}" Header="Name"/> <DataGridTextColumn x:Name="cost" Binding="{Binding Path=Cost, Mode=TwoWay}" Header="Cost"/> <DataGridTextColumn x:Name="Quantity" Binding="{Binding Path=Quantity, Mode=TwoWay}" Header="Quantity"/> <DataGridTextColumn x:Name="total" Binding="{Binding Path=Total, Mode=TwoWay}" Header="Total"/> </DataGrid.Columns>

Luego en ViewModel

private ObservableCollection<Product> _product; public ObservableCollection<Product> MyProduct { get { return _product; } set { Set(ref _product, value); } } public ProductViewModel(IDataService proxy) { _proxy = proxy; LoadCommand = new RelayCommand(DoGetProducts); EndEdit = new RelayCommand<DataGridCellEditEndingEventArgs>(DoEndEdit); } private void DoEndEdit(DataGridCellEditEndingEventArgs obj) { DataGridRow row = obj.Row; Product p = (Product)row.Item; p.Total = p.Cost*p.Quantity; _proxy.SaveAll(); }

Luego en el Modelo:

public class DataService : IDataService { ProductEntities context; public DataService() { context = new ProductEntities(); } public ObservableCollection<Product> GetProducts(){ ObservableCollection<Product> products = new ObservableCollection<Product>(); foreach(var p in context.Products.Tolist()){ products.add(p); } return products; } public void SaveAll() { context.SaveChanges(); } }

La cuadrícula de datos está cargando productos pero no está actualizando el Total cuando se modifican el Costo y la Cantidad. Además, no guarda los cambios en la base de datos


La salida será así: -

Cambia tu Xaml como dar a continuación

<DataGrid x:Name="dataGrid" Margin="5,5,10,5" AutoGenerateColumns="False" HorizontalAlignment="Stretch" ItemsSource="{Binding ProductList}" VerticalAlignment="Stretch" Height="566" > <i:Interaction.Triggers> <i:EventTrigger EventName="RowEditEnding" "> <cmd:EventToCommand Command="{Binding EndEdit}" PassEventArgsToCommand="True"/> </i:EventTrigger> </i:Interaction.Triggers> <DataGrid.Columns> <DataGridTextColumn x:Name="Id" Binding="{Binding Path=Id, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" Header="Id"/> <DataGridTextColumn x:Name="name" Binding="{Binding Path=Name, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" Header="Name"/> <DataGridTextColumn x:Name="cost" Binding="{Binding Path=Cost, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" Header="Cost"/> <DataGridTextColumn x:Name="Quantity" Binding="{Binding Path=Quantity, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" Header="Quantity"/> <DataGridTextColumn x:Name="total" Binding="{Binding Path=Total, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" Header="Total"/> </DataGrid.Columns>

Y en View Model you Bindings sea como

public BindingList<Product> ProductList { get { return _proxy.ProductList; } }

Y el comando EndEdit debería ejecutar la siguiente función

private void ExecuteEndEdit(DataGridRowEditEndingEventArgs param) { var product = param.Row.Item as Product; var result = ProductList.FirstOrDefault(p => p.Id == product.Id); var index= ProductList.IndexOf(result); result.Total = result.Cost * result.Quantity; ProductList.ResetItem(index); }

Su IDataService puede exponer lista de vinculación como

public class DataService : IDataService { ProductEntities context; public DataService() { context = new ProductEntities(); } public BindingList<Product> ProductList { get { //EDIT: YOU HAVE TO CALL context.Products.Load(); OR IT WILL RETURN EMPTY RESULTS context.Products.Load(); return context.Products.Local.ToBindingList<Product>(); } } public void SaveAll() { context.SaveChanges(); } }

El Context.Save guardará su código.